Compare commits

...

3 Commits

Author SHA1 Message Date
Joel Falknau
498b876572
begin docs for new authenticator 2024-12-30 13:29:25 +10:00
Joel Falknau
7559b7ac09
Mumble Server Parameter 2024-12-30 13:28:36 +10:00
Joel Falknau
9e39769ad3
model docs 2024-12-30 13:28:05 +10:00
8 changed files with 187 additions and 161 deletions

View File

@ -56,7 +56,20 @@ from allianceauth import __version__ # noqa
from allianceauth.services.modules.mumble.models import MumbleServerServer, MumbleUser, TempUser # noqa from allianceauth.services.modules.mumble.models import MumbleServerServer, MumbleUser, TempUser # noqa
def main() -> None: def main(server_id: int = 1) -> None:
"""_summary_
Args:
server_id (int, optional): _description_. Defaults to 1.
Raises:
e: _description_
Murmur.InvalidSecretException: _description_
e: _description_
Returns:
_type_: _description_
"""
slicedir = Ice.getSliceDir() slicedir = Ice.getSliceDir()
if not slicedir: if not slicedir:
slicedir = ["-I/usr/share/Ice/slice", "-I/usr/share/slice"] slicedir = ["-I/usr/share/Ice/slice", "-I/usr/share/slice"]
@ -64,7 +77,7 @@ def main() -> None:
slicedir = ['-I' + slicedir] slicedir = ['-I' + slicedir]
package_dir = next(iter(importlib.util.find_spec('allianceauth.services.modules.mumble').submodule_search_locations)) package_dir = next(iter(importlib.util.find_spec('allianceauth.services.modules.mumble').submodule_search_locations))
package_ice = os.path.join(package_dir, MumbleServerServer.objects.get(id=1).slice) package_ice = os.path.join(package_dir, server_config_obj.slice)
logger.info(f"Using slice file: {package_ice}") logger.info(f"Using slice file: {package_ice}")
slicedir.append("-I" + os.path.dirname(package_ice)) slicedir.append("-I" + os.path.dirname(package_ice))
@ -75,6 +88,8 @@ def main() -> None:
except ImportError: except ImportError:
import Murmur # Mumble <=1.5.17 import Murmur # Mumble <=1.5.17
server_config_obj = MumbleServerServer.objects.get(id=server_id)
class AllianceAuthAuthenticatorApp(Ice.Application): class AllianceAuthAuthenticatorApp(Ice.Application):
def run(self, args) -> int: def run(self, args) -> int:
self.shutdownOnInterrupt() self.shutdownOnInterrupt()
@ -82,7 +97,7 @@ def main() -> None:
if not self.initializeIceConnection(): if not self.initializeIceConnection():
return 1 return 1
if MumbleServerServer.objects.get(id=1).watchdog > 0: if server_config_obj.watchdog > 0:
self.failedWatch = True self.failedWatch = True
self.checkConnection() self.checkConnection()
@ -102,13 +117,13 @@ def main() -> None:
""" """
ice = self.communicator() ice = self.communicator()
logger.debug("Using shared ice secret") logger.debug("Using shared ice secret")
ice.getImplicitContext().put("secret", MumbleServerServer.objects.get(id=1).secret) ice.getImplicitContext().put("secret", server_config_obj.secret)
logger.info(f"Connecting to Ice server ({MumbleServerServer.objects.get(id=1).ip}:{MumbleServerServer.objects.get(id=1).port})") logger.info(f"Connecting to Ice server ({server_config_obj.ip}:{server_config_obj.port})")
base = ice.stringToProxy(f"Meta:tcp -h {MumbleServerServer.objects.get(id=1).ip} -p {MumbleServerServer.objects.get(id=1).port}") base = ice.stringToProxy(f"Meta:tcp -h {server_config_obj.ip} -p {server_config_obj.port}")
self.meta = Murmur.MetaPrx.uncheckedCast(base) self.meta = Murmur.MetaPrx.uncheckedCast(base)
adapter = ice.createObjectAdapterWithEndpoints("Callback.Client", f"tcp -h {MumbleServerServer.objects.get(id=1).endpoint}") adapter = ice.createObjectAdapterWithEndpoints("Callback.Client", f"tcp -h {server_config_obj.endpoint}")
adapter.activate() adapter.activate()
metacbprx = adapter.addWithUUID(metaCallback(self)) metacbprx = adapter.addWithUUID(metaCallback(self))
@ -136,11 +151,11 @@ def main() -> None:
self.meta.addCallback(self.metacb) self.meta.addCallback(self.metacb)
for server in self.meta.getBootedServers(): for server in self.meta.getBootedServers():
if server.id() in MumbleServerServer.objects.get(id=1).virtual_servers_list(): if server.id() in server_config_obj.virtual_servers_list():
logger.info("Setting authenticator for virtual server %d", server.id()) logger.info("Setting authenticator for virtual server %d", server.id())
server.setAuthenticator(self.auth) server.setAuthenticator(self.auth)
server.addCallback(self.servercb) server.addCallback(self.servercb)
if MumbleServerServer.objects.get(id=1).idler_handler: if server_config_obj.idler_handler:
idler_handler(server) idler_handler(server)
except (Murmur.InvalidSecretException, Ice.UnknownUserException, Ice.ConnectionRefusedException) as e: except (Murmur.InvalidSecretException, Ice.UnknownUserException, Ice.ConnectionRefusedException) as e:
@ -170,12 +185,12 @@ def main() -> None:
else: else:
self.failedWatch = False self.failedWatch = False
except Ice.Exception as e: except Ice.Exception as e:
logger.error(f"Failed connection check, will retry in next watchdog run ({MumbleServerServer.objects.get(id=1).watchdog}s)") logger.error(f"Failed connection check, will retry in next watchdog run ({server_config_obj.watchdog}s)")
logger.exception(e) logger.exception(e)
self.failedWatch = True self.failedWatch = True
# Renew the timer # Renew the timer
self.watchdog = Timer(MumbleServerServer.objects.get(id=1).watchdog, self.checkConnection) self.watchdog = Timer(server_config_obj.watchdog, self.checkConnection)
self.watchdog.start() self.watchdog.start()
def checkSecret(func): def checkSecret(func):
@ -183,7 +198,7 @@ def main() -> None:
Decorator that checks whether the server transmitted the right secret Decorator that checks whether the server transmitted the right secret
if a secret is supposed to be used. if a secret is supposed to be used.
""" """
if not MumbleServerServer.objects.get(id=1).secret: if not server_config_obj.secret:
return func return func
def newfunc(*args, **kws): def newfunc(*args, **kws):
@ -192,7 +207,7 @@ def main() -> None:
else: else:
current = args[-1] current = args[-1]
if not current or "secret" not in current.ctx or current.ctx["secret"] != MumbleServerServer.objects.get(id=1).secret: if not current or "secret" not in current.ctx or current.ctx["secret"] != server_config_obj.secret:
logger.error("Server transmitted invalid secret. Possible injection attempt.") logger.error("Server transmitted invalid secret. Possible injection attempt.")
raise Murmur.InvalidSecretException() raise Murmur.InvalidSecretException()
@ -242,7 +257,7 @@ def main() -> None:
This function is called when a virtual server is started This function is called when a virtual server is started
and makes sure an authenticator gets attached if needed. and makes sure an authenticator gets attached if needed.
""" """
if server.id() in MumbleServerServer.objects.get(id=1).virtual_servers_list(): if server.id() in server_config_obj.virtual_servers_list():
logger.info("Setting authenticator for virtual server %d", server.id()) logger.info("Setting authenticator for virtual server %d", server.id())
try: try:
server.setAuthenticator(self.app.auth) server.setAuthenticator(self.app.auth)
@ -266,7 +281,7 @@ def main() -> None:
# Only try to output the server id if we think we are still connected to prevent # Only try to output the server id if we think we are still connected to prevent
# flooding of our thread pool # flooding of our thread pool
try: try:
if server.id() in MumbleServerServer.objects.get(id=1).virtual_servers_list(): if server.id() in server_config_obj.virtual_servers_list():
logger.info(f"Authenticated virtual server {server.id()} got stopped") logger.info(f"Authenticated virtual server {server.id()} got stopped")
else: else:
logger.debug(f"Virtual server {server.id()} got stopped") logger.debug(f"Virtual server {server.id()} got stopped")
@ -276,7 +291,7 @@ def main() -> None:
logger.debug("Server shutdown stopped a virtual server") logger.debug("Server shutdown stopped a virtual server")
if MumbleServerServer.objects.get(id=1).reject_on_error: # Python 2.4 compat if server_config_obj.reject_on_error: # Python 2.4 compat
authenticateFortifyResult = (-1, None, None) authenticateFortifyResult = (-1, None, None)
else: else:
authenticateFortifyResult = (-2, None, None) authenticateFortifyResult = (-2, None, None)
@ -328,7 +343,7 @@ def main() -> None:
users = self.server.getUsers() users = self.server.getUsers()
for (userid, auser) in users.items(): for (userid, auser) in users.items():
if auser.userid > (MumbleServerServer.objects.get(id=1).offset * 2): if auser.userid > (server_config_obj.offset * 2):
self.server.kickUser(auser.session, "Kicking all temp users! :-)") self.server.kickUser(auser.session, "Kicking all temp users! :-)")
self.server.sendMessage(user.session, "All templink clients kicked!") self.server.sendMessage(user.session, "All templink clients kicked!")
@ -373,11 +388,11 @@ def main() -> None:
logger.debug("checking password with hash function: %s" % mumble_user.hashfn) logger.debug("checking password with hash function: %s" % mumble_user.hashfn)
if allianceauth_check_hash(pw, mumble_user.pwhash, mumble_user.hashfn): if allianceauth_check_hash(pw, mumble_user.pwhash, mumble_user.hashfn):
logger.info(f'User authenticated: {mumble_user.display_name} {mumble_user.user_id + MumbleServerServer.objects.get(id=1).offset}') logger.info(f'User authenticated: {mumble_user.display_name} {mumble_user.user_id + server_config_obj.offset}')
logger.debug("Group memberships: %s", mumble_user.group_string()) logger.debug("Group memberships: %s", mumble_user.group_string())
return (mumble_user.user_id + MumbleServerServer.objects.get(id=1).offset, mumble_user.display_name, mumble_user.group_string()) return (mumble_user.user_id + server_config_obj.offset, mumble_user.display_name, mumble_user.group_string())
logger.info( logger.info(
f'Failed authentication attempt for user: {name} {mumble_user.user_id + MumbleServerServer.objects.get(id=1).offset}') f'Failed authentication attempt for user: {name} {mumble_user.user_id + server_config_obj.offset}')
return (AUTH_REFUSED, None, None) return (AUTH_REFUSED, None, None)
@fortifyIceFu((False, None)) @fortifyIceFu((False, None))
@ -401,10 +416,10 @@ def main() -> None:
return -2 # FALL_THROUGH return -2 # FALL_THROUGH
try: try:
return (MumbleUser.objects.get(username=name).pk + MumbleServerServer.objects.get(id=1).offset) return (MumbleUser.objects.get(username=name).pk + server_config_obj.offset)
except MumbleUser.DoesNotExist: except MumbleUser.DoesNotExist:
try: try:
return (TempUser.objects.get(username=name).pk + MumbleServerServer.objects.get(id=1).offset * 2) return (TempUser.objects.get(username=name).pk + server_config_obj.offset * 2)
except TempUser.DoesNotExist: except TempUser.DoesNotExist:
return -2 # FALL_THROUGH return -2 # FALL_THROUGH
@ -414,15 +429,15 @@ def main() -> None:
""" """
Gets called to get the username for a given id Gets called to get the username for a given id
""" """
if id < MumbleServerServer.objects.get(id=1).offset: if id < server_config_obj.offset:
return "" # FALL_THROUGH return "" # FALL_THROUGH
try: try:
mumble_user = MumbleUser.objects.get(user_id=id - MumbleServerServer.objects.get(id=1).offset) mumble_user = MumbleUser.objects.get(user_id=id - server_config_obj.offset)
mumble_user.username mumble_user.username
except MumbleUser.DoesNotExist: except MumbleUser.DoesNotExist:
try: try:
mumble_user = TempUser.objects.get(user_id=id - MumbleServerServer.objects.get(id=1).offset * 2) mumble_user = TempUser.objects.get(user_id=id - server_config_obj.offset * 2)
mumble_user.username mumble_user.username
except TempUser.DoesNotExist: except TempUser.DoesNotExist:
return "" # FALL_THROUGH return "" # FALL_THROUGH
@ -430,7 +445,7 @@ def main() -> None:
# I dont quite rightly know why we have this # I dont quite rightly know why we have this
# SuperUser shouldnt be in our Authenticator? # SuperUser shouldnt be in our Authenticator?
# But Maybe it can be? # But Maybe it can be?
if MumbleUser.objects.get(user_id=id - MumbleServerServer.objects.get(id=1).offset).username == "SuperUser": if MumbleUser.objects.get(user_id=id - server_config_obj.offset).username == "SuperUser":
logger.debug('idToName %d -> "SuperUser" caught') logger.debug('idToName %d -> "SuperUser" caught')
return "" # FALL_THROUGH return "" # FALL_THROUGH
else: else:
@ -442,15 +457,15 @@ def main() -> None:
""" """
Gets called to get the corresponding texture for a user Gets called to get the corresponding texture for a user
""" """
if MumbleServerServer.objects.get(id=1).avatar_enable is False: if server_config_obj.avatar_enable is False:
logger.debug(f"idToTexture {id} -> avatar display disabled, fall through") logger.debug(f"idToTexture {id} -> avatar display disabled, fall through")
return "" # FALL_THROUGH return "" # FALL_THROUGH
if id < MumbleServerServer.objects.get(id=1).offset: if id < server_config_obj.offset:
return "" # FALL_THROUGH return "" # FALL_THROUGH
try: try:
avatar_url = MumbleUser.objects.get(user_id=id - MumbleServerServer.objects.get(id=1).offset).user.profile.main_character.portrait_url() avatar_url = MumbleUser.objects.get(user_id=id - server_config_obj.offset).user.profile.main_character.portrait_url()
except MumbleUser.DoesNotExist: except MumbleUser.DoesNotExist:
logger.debug(f"idToTexture {id} -> MumbleUser.DoesNotExist, Fall Through") logger.debug(f"idToTexture {id} -> MumbleUser.DoesNotExist, Fall Through")
return "" # FALL_THROUGH return "" # FALL_THROUGH
@ -520,7 +535,7 @@ def main() -> None:
return {} return {}
logger.debug(f'getRegisteredUsers -> {len(mumble_users)} results for filter {filter}') logger.debug(f'getRegisteredUsers -> {len(mumble_users)} results for filter {filter}')
return {mumble_user.user_id + MumbleServerServer.objects.get(id=1).offset: mumble_user.username for mumble_user in mumble_users} return {mumble_user.user_id + server_config_obj.offset: mumble_user.username for mumble_user in mumble_users}
@fortifyIceFu(-1) @fortifyIceFu(-1)
@checkSecret @checkSecret
@ -586,30 +601,30 @@ def idler_handler(server) -> None:
logger.debug(f"IdleHandler: Skipping User {user.name}, This happens occasionally") logger.debug(f"IdleHandler: Skipping User {user.name}, This happens occasionally")
continue continue
if user_idlesecs > MumbleServerServer.objects.get(id=1).idler_handler.seconds: if user_idlesecs > server_config_obj.idler_handler.seconds:
logger.debug( logger.debug(
f"IdleHandler: User {user.name} is AFK, for {user_idlesecs}/{MumbleServerServer.objects.get(id=1).idler_handler.seconds}" f"IdleHandler: User {user.name} is AFK, for {user_idlesecs}/{server_config_obj.idler_handler.seconds}"
) )
state = server.getState(user.session) state = server.getState(user.session)
if state: if state:
# AllowList > DenyList # AllowList > DenyList
if MumbleServerServer.objects.get(id=1).idler_handler.denylist is False: if server_config_obj.idler_handler.denylist is False:
if state.channel not in MumbleServerServer.objects.get(id=1).idler_handler.list: if state.channel not in server_config_obj.idler_handler.list:
return return
elif MumbleServerServer.objects.get(id=1).idler_handler.denylist is True: elif server_config_obj.idler_handler.denylist is True:
if state.channel in MumbleServerServer.objects.get(id=1).idler_handler.list: if state.channel in server_config_obj.idler_handler.list:
return return
if state.channel == MumbleServerServer.objects.get(id=1).idler_handler.channel: if state.channel == server_config_obj.idler_handler.channel:
return return
state.channel = MumbleServerServer.objects.get(id=1).idler_handler.channel state.channel = server_config_obj.idler_handler.channel
state.selfMute = True state.selfMute = True
state.selfDeaf = True state.selfDeaf = True
server.setState(state) server.setState(state)
logger.debug(f"IdleHandler: Moved AFK User {user.name}") logger.debug(f"IdleHandler: Moved AFK User {user.name}")
Timer(MumbleServerServer.objects.get(id=1).idler_handler.interval, idler_handler, (server,)).start() Timer(server_config_obj.idler_handler.interval, idler_handler, (server,)).start()
if __name__ == "__main__": if __name__ == "__main__":

View File

@ -0,0 +1,15 @@
from allianceauth.services.modules.mumble import authenticator
from django.core.management.base import BaseCommand
class Command(BaseCommand):
help = 'Run the Mumble Authenticator'
def add_arguments(self, parser) -> None:
parser.add_argument(
'--server_id', action='store', default=1,
help='Run the Mumble Authenticator for the given Server Configuration ID')
def handle(self, *args, **options) -> None:
authenticator.main()

View File

@ -0,0 +1,27 @@
# Generated by Django 4.2.16 on 2024-12-29 13:14
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('mumble', '0016_templink_alter_mumbleuser_last_connect_and_more'),
]
operations = [
migrations.AlterModelOptions(
name='tempuser',
options={'permissions': (), 'verbose_name': 'Temp User', 'verbose_name_plural': 'Temp Users'},
),
migrations.AlterField(
model_name='idlerhandler',
name='denylist',
field=models.BooleanField(default=True, help_text='True for DenyList, False for Allowlist', verbose_name='DenyList'),
),
migrations.AlterField(
model_name='idlerhandler',
name='list',
field=models.CharField(default='', max_length=50, verbose_name='Allow/Deny list'),
),
]

View File

@ -219,8 +219,8 @@ class IdlerHandler(models.Model):
seconds = models.SmallIntegerField(_("Idle Seconds"), default=3600) seconds = models.SmallIntegerField(_("Idle Seconds"), default=3600)
interval = models.SmallIntegerField(_("Run Interval"), default=60) interval = models.SmallIntegerField(_("Run Interval"), default=60)
channel = models.SmallIntegerField(_("AFK Channel")) channel = models.SmallIntegerField(_("AFK Channel"))
denylist = models.BooleanField(_(""), default=True) denylist = models.BooleanField(_("DenyList"), default=True, help_text="True for DenyList, False for Allowlist")
list = models.CharField(_(""), max_length=50, default="") list = models.CharField(_("Allow/Deny list"), max_length=50, default="")
class Meta: class Meta:
verbose_name = _("Idler Handler") verbose_name = _("Idler Handler")

View File

@ -6,25 +6,25 @@ Mumble is a free voice chat server. While not as flashy as TeamSpeak, it has all
## Configuring Auth ## Configuring Auth
In your auth project's settings file (`aa-docker/conf/local.py`), do the following: In your auth project's settings file (`myauth/settings/local.py`), do the following:
- Add `'allianceauth.services.modules.mumble',` to `INSTALLED_APPS` in your `local.py` - Add `'allianceauth.services.modules.mumble',` to your `INSTALLED_APPS` list
- Append the following to your auth project's settings file: - Set `MUMBLE_URL` to the public address of your mumble server. Do not include any leading `http://` or `mumble://`.
Example config:
```python ```python
# Installed apps
INSTALLED_APPS += [
# ...
'allianceauth.services.modules.mumble'
# ...
]
# Mumble Configuration # Mumble Configuration
MUMBLE_URL = "mumble.example.com" MUMBLE_URL = "mumble.example.com"
``` ```
Add the following lines to your `.env` file
```env
# Mumble
MUMBLE_SUPERUSER_PASSWORD = superuser_password
MUMBLE_ICESECRETWRITE = icesecretwrite
MUMBLE_SERVERPASSWORD = serverpassword
```
Finally, restart your stack and run migrations Finally, restart your stack and run migrations
```shell ```shell
@ -33,16 +33,29 @@ docker compose exec allianceauth_gunicorn bash
auth migrate auth migrate
``` ```
## Configuring Authenticator
The Authenticator is configured via Django Admin, visit `/admin/mumble/mumbleserverserver/` in
Name: TEST
Host IP Address: 127.0.0.1
Endpoint IP Address: 127.0.0.1
Port: 6502
ICE Secret: ICESECRETWRITE
Watchdog Interval: 30
Slice: MumbleServer.ice (Mumble >=1.5.17)
Virtual Servers: 1
Enable EVE Avatars
Reject Unauthenticated
ID Offset: 1000000000
Idler Handler:
## Docker Installations ## Docker Installations
### Installing Mumble and Authenticator ### Installing Mumble and Authenticator
Inside your `aa-docker` directory, clone the authenticator to a sub directory as follows
```shell
git clone https://gitlab.com/allianceauth/mumble-authenticator.git
```
Add the following to your `docker-compose.yml` under the `services:` section Add the following to your `docker-compose.yml` under the `services:` section
```docker ```docker
@ -66,27 +79,16 @@ Add the following to your `docker-compose.yml` under the `services:` section
max-size: "10Mb" max-size: "10Mb"
max-file: "5" max-file: "5"
mumble-authenticator: allianceauth_mumble_authenticator:
build: container_name: allianceauth_mumble_authenticator
context: . <<: [*allianceauth-base]
dockerfile: ./mumble-authenticator/Dockerfile entrypoint: [
restart: always "python",
volumes: "manage.py",
- ./mumble-authenticator/authenticator.py:/authenticator.py "mumble_authenticator",
- ./mumble-authenticator/authenticator.ini.docker:/authenticator.ini "--server_id=1"
environment: ]
- MUMBLE_SUPERUSER_PASSWORD=${MUMBLE_SUPERUSER_PASSWORD}
- MUMBLE_CONFIG_ice="tcp -h 127.0.0.1 -p 6502"
- MUMBLE_CONFIG_icesecretwrite=${MUMBLE_ICESECRETWRITE}
- MUMBLE_CONFIG_serverpassword=${MUMBLE_SERVERPASSWORD}
depends_on:
- mumble-server
- auth_mysql
logging:
driver: "json-file"
options:
max-size: "10Mb"
max-file: "5"
``` ```
## Permissions ## Permissions

View File

@ -49,26 +49,6 @@ sudo yum install mumble-server
::: :::
:::: ::::
### Installing Mumble Authenticator
Next, we need to download the latest authenticator release from the [authenticator repository](https://gitlab.com/allianceauth/mumble-authenticator).
```shell
git clone https://gitlab.com/allianceauth/mumble-authenticator /home/allianceserver/mumble-authenticator
```
We will now install the authenticator into your Auth virtual environment. Please make sure to activate it first:
```shell
source /home/allianceserver/venv/auth/bin/activate
```
Install the python dependencies for the mumble authenticator. Note that this process can take 2 to 10 minutes to complete.
```shell
pip install -r requirements.txt
```
## Configuring Mumble Server ## Configuring Mumble Server
Mumble ships with a configuration file that needs customization. By default, it's located at `/etc/mumble-server.ini`. Open it with your favorite text editor: Mumble ships with a configuration file that needs customization. By default, it's located at `/etc/mumble-server.ini`. Open it with your favorite text editor:
@ -102,66 +82,6 @@ sudo service mumble-server restart
That's it! Your server is ready to be connected to at example.com:64738 That's it! Your server is ready to be connected to at example.com:64738
## Configuring Mumble Authenticator
The ICE authenticator lives in the mumble-authenticator repository, cd to the directory where you cloned it.
Make a copy of the default config:
```shell
cp authenticator.ini.example authenticator.ini
```
Edit `authenticator.ini` and change these values:
- `[database]`
- `user =` your allianceserver MySQL user
- `password =` your allianceserver MySQL user's password
- `[ice]`
- `secret =` the `icewritesecret` password set earlier
Test your configuration by starting it:
```shell
python /home/allianceserver/mumble-authenticator/authenticator.py
```
And finally, ensure the allianceserver user has read/write permissions to the mumble authenticator files before proceeding:
```shell
sudo chown -R allianceserver:allianceserver /home/allianceserver/mumble-authenticator
```
The authenticator needs to be running 24/7 to validate users on Mumble. This can be achieved by adding a section to your auth project's supervisor config file like the following example:
```ini
[program:authenticator]
command=/home/allianceserver/venv/auth/bin/python authenticator.py
directory=/home/allianceserver/mumble-authenticator
user=allianceserver
stdout_logfile=/home/allianceserver/myauth/log/authenticator.log
stderr_logfile=/home/allianceserver/myauth/log/authenticator.log
autostart=true
autorestart=true
startsecs=10
priority=996
```
In addition, we'd recommend adding the authenticator to Auth's restart group in your supervisor conf. For that, you need to add it to the group line as shown in the following example:
```ini
[group:myauth]
programs=beat,worker,gunicorn,authenticator
priority=999
```
To enable the changes in your supervisor configuration, you need to restart the supervisor process itself. And before we do that, we are shutting down the current Auth supervisors gracefully:
```shell
sudo supervisor stop myauth:
sudo systemctl restart supervisor
```
## Configuring Auth ## Configuring Auth
In your auth project's settings file (`myauth/settings/local.py`), do the following: In your auth project's settings file (`myauth/settings/local.py`), do the following:
@ -187,10 +107,57 @@ Finally, run migrations and restart your supervisor to complete the setup:
```shell ```shell
python /home/allianceserver/myauth/manage.py migrate python /home/allianceserver/myauth/manage.py migrate
supervisorctl restart myauth:
``` ```
## Configuring Authenticator
The Authenticator is configured via Django Admin, visit `/admin/mumble/mumbleserverserver/` in
Name: TEST
Host IP Address: 127.0.0.1
Endpoint IP Address: 127.0.0.1
Port: 6502
ICE Secret: ICESECRETWRITE
Watchdog Interval: 30
Slice: MumbleServer.ice (Mumble >=1.5.17)
Virtual Servers: 1
Enable EVE Avatars
Reject Unauthenticated
ID Offset: 1000000000
Idler Handler:
## Running Authenticator
The authenticator needs to be running 24/7 to validate users on Mumble. This can be achieved by adding a section to your auth project's supervisor config file like the following example:
```ini
[program:authenticator]
command=/home/allianceserver/venv/auth/bin/python manage.py mumble_authenticator
directory=/home/allianceserver/myauth/
stdout_logfile=/home/allianceserver/myauth/log/authenticator.log
stderr_logfile=/home/allianceserver/myauth/log/authenticator.log
autostart=true
autorestart=true
startsecs=10
priority=996
```
In addition, we'd recommend adding the authenticator to Auth's restart group in your supervisor conf. For that, you need to add it to the group line as shown in the following example:
```ini
[group:myauth]
programs=beat,worker,gunicorn,authenticator
priority=999
```
To enable the changes in your supervisor configuration, you need to restart the supervisor process itself. And before we do that, we are shutting down the current Auth supervisors gracefully:
```shell ```shell
supervisorctl restart myauth: sudo supervisor stop myauth:
sudo systemctl restart supervisor
``` ```
## Permissions ## Permissions