Move config files to /etc/micronas/, fix WebDAV passwd permissions
- /etc/micronas.env → /etc/micronas/micronas.env - /etc/micronas-webdav.passwd → /etc/micronas/webdav.passwd - _save_credentials creates /etc/micronas/ if missing - _write_webdav_conf: chown root:www-data on passwd file so Apache can read it - micronas.service EnvironmentFile updated - README: credentials now set via /setup, config dir step added Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
a29862860d
commit
7194aaf7e9
3 files changed
+13
-11
No files matched your search
@@ -44,16 +44,15 @@ python3 -m venv /opt/micronas/venv
|
|||||||
/opt/micronas/venv/bin/pip install flask gunicorn
|
/opt/micronas/venv/bin/pip install flask gunicorn
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Credentials
|
### 4. Config directory
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cat > /etc/micronas.env <<EOF
|
mkdir -p /etc/micronas
|
||||||
MICRONAS_USER=admin
|
chmod 700 /etc/micronas
|
||||||
MICRONAS_PASS=changeme
|
|
||||||
EOF
|
|
||||||
chmod 600 /etc/micronas.env
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Credentials are set on first login via the `/setup` page in the browser. No manual env file editing needed.
|
||||||
|
|
||||||
### 5. systemd service
|
### 5. systemd service
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -93,7 +92,7 @@ Note: SMB/NFS/user management calls require root and the relevant daemons — ru
|
|||||||
|
|
||||||
## Auth
|
## Auth
|
||||||
|
|
||||||
All routes require a login session. Go to `http://<lxc-ip>:5000` — you will be redirected to the login page automatically. Credentials come from `MICRONAS_USER` / `MICRONAS_PASS` in `/etc/micronas.env`. If `MICRONAS_PASS` is not set the app starts unprotected and logs a warning — do not do this in production.
|
All routes require a login session. On first run you are redirected to `/setup` to create the admin account. Credentials are stored hashed in `/etc/micronas/micronas.env`. The WebDAV htpasswd file lives at `/etc/micronas/webdav.passwd` (readable by `www-data`, not world-readable).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,8 @@ VALID_NAME = re.compile(r'^[A-Za-z0-9_-]+$')
|
|||||||
VALID_NFS_CLIENT = re.compile(r'^[A-Za-z0-9.*:/\-]+$')
|
VALID_NFS_CLIENT = re.compile(r'^[A-Za-z0-9.*:/\-]+$')
|
||||||
ALLOWED_PATH_BASE = Path('/srv').resolve()
|
ALLOWED_PATH_BASE = Path('/srv').resolve()
|
||||||
|
|
||||||
_ENV_FILE = '/etc/micronas.env'
|
_CONF_DIR = '/etc/micronas'
|
||||||
|
_ENV_FILE = '/etc/micronas/micronas.env'
|
||||||
|
|
||||||
# Mutable credential store — updated by setup/change without restart (single gunicorn worker).
|
# Mutable credential store — updated by setup/change without restart (single gunicorn worker).
|
||||||
_creds = {
|
_creds = {
|
||||||
@@ -48,6 +49,7 @@ def _verify_password(password):
|
|||||||
|
|
||||||
def _save_credentials(user, password):
|
def _save_credentials(user, password):
|
||||||
h = _hash_password(password)
|
h = _hash_password(password)
|
||||||
|
os.makedirs(_CONF_DIR, exist_ok=True)
|
||||||
Path(_ENV_FILE).write_text(f'MICRONAS_USER={user}\nMICRONAS_PASS_HASH={h}\n')
|
Path(_ENV_FILE).write_text(f'MICRONAS_USER={user}\nMICRONAS_PASS_HASH={h}\n')
|
||||||
os.chmod(_ENV_FILE, 0o600)
|
os.chmod(_ENV_FILE, 0o600)
|
||||||
_creds['user'] = user
|
_creds['user'] = user
|
||||||
@@ -291,7 +293,7 @@ def add_nfs_share(path, clients, ro=False):
|
|||||||
# ===== WEBDAV =====
|
# ===== WEBDAV =====
|
||||||
|
|
||||||
WEBDAV_CONF = '/etc/apache2/conf-available/micronas-webdav.conf'
|
WEBDAV_CONF = '/etc/apache2/conf-available/micronas-webdav.conf'
|
||||||
WEBDAV_PASSWD = '/etc/micronas-webdav.passwd'
|
WEBDAV_PASSWD = '/etc/micronas/webdav.passwd'
|
||||||
_WEBDAV_MARK = 'MICRONAS'
|
_WEBDAV_MARK = 'MICRONAS'
|
||||||
|
|
||||||
|
|
||||||
@@ -340,9 +342,10 @@ def _write_webdav_conf(shares):
|
|||||||
]
|
]
|
||||||
with open(WEBDAV_CONF, 'w') as f:
|
with open(WEBDAV_CONF, 'w') as f:
|
||||||
f.writelines(lines)
|
f.writelines(lines)
|
||||||
# Ensure the passwd file exists so Apache doesn't 500 before any user has logged in
|
# Ensure passwd file exists and is readable by www-data (Apache) but not world-readable
|
||||||
if not os.path.exists(WEBDAV_PASSWD):
|
if not os.path.exists(WEBDAV_PASSWD):
|
||||||
Path(WEBDAV_PASSWD).touch(mode=0o640)
|
Path(WEBDAV_PASSWD).touch(mode=0o640)
|
||||||
|
subprocess.run(['chown', 'root:www-data', WEBDAV_PASSWD], capture_output=True)
|
||||||
subprocess.run(['a2enconf', 'micronas-webdav'], capture_output=True)
|
subprocess.run(['a2enconf', 'micronas-webdav'], capture_output=True)
|
||||||
subprocess.run(['systemctl', 'reload', 'apache2'], capture_output=True)
|
subprocess.run(['systemctl', 'reload', 'apache2'], capture_output=True)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -7,7 +7,7 @@ Wants=smbd.service nfs-server.service
|
|||||||
Type=simple
|
Type=simple
|
||||||
User=root
|
User=root
|
||||||
WorkingDirectory=/opt/micronas
|
WorkingDirectory=/opt/micronas
|
||||||
EnvironmentFile=/etc/micronas.env
|
EnvironmentFile=/etc/micronas/micronas.env
|
||||||
ExecStart=/opt/micronas/venv/bin/gunicorn -w 1 -b 0.0.0.0:5000 app:app
|
ExecStart=/opt/micronas/venv/bin/gunicorn -w 1 -b 0.0.0.0:5000 app:app
|
||||||
Restart=on-failure
|
Restart=on-failure
|
||||||
RestartSec=5
|
RestartSec=5
|
||||||
|
|||||||
Reference in new issue
Block a user