Ethan1
September 25, 2025, 2:43pm
1
Timestamp
Notes
0:38
Deployed the LTS option Ubuntu 24.04 x64
2:43
Enabled the Uncomplicated Firewall before creating an A record
4:03
created A record
login as root
4:37
ran sudo adduser --disabled-password --gecos "" jupyter
4:41
ran sudo usermod -aG sudo jupyter
4:46
ran apt update
4:59
ran apt install -y python3-venv python3-pip nginx ufw
5:38
ran -iu jupyter
which failed
5:53
ran sudo -iu jupyter
which worked
5:59
ran python3 -m venv ~/jlab-venv
6:08
ran ~/jlab-venv/bin/pip install --upgrade pip
6:17
ran ~/jlab-venv/bin/pip install jupyterlab jupyterlab-git
6:49
ran ~/jlab-venv/bin/jupyter server --generate-config
7:01
ran python3 -c "from jupyter_server.auth import passwd; print(passwd())"
which failed
7:44
ran ~/jlab-venv/bin/python -c "from jupyter_server.auth import passwd; print(passwd())"
7:46
entered the password that will be used to login to Jupyter Lab webpage
12:20
used PuttyGen to get OpenSSH key from the .ppk
17:13
in cmd
i ran scp -i C:\Users\ppyem\Documents\id_rsa root@134.209.30.67:/home/jupyter/.jupyter/jupyter_server_config.py C:\Users\ppyem\Documents\
to get the full configuration file locally
Timestamp
Notes
18:57
i ran nano ~/.jupyter/jupyter_server_config.py
20:09
i appended to bootom
c.ServerApp.ip = "127.0.0.1"
c.ServerApp.port = 8888
c.ServerApp.open_browser = False
c.ServerApp.allow_remote_access = True
c.ServerApp.trust_xheaders = True
# require login everywhere
c.ServerApp.allow_unauthenticated_access = False
# authentication
c.ServerApp.token = ""
c.ServerApp.password = "argon2:$argon2id$v=19$m=10240,t=10,p=8$XOEmNWiKRa+XjdjRYROfPg$ob4eQEU3/Cp+uL9dfT6SF9XHMulApkh6y/fELz3C61A"
Timestamp
Notes
20:29
i ran nano ~/.jupyter/jupyter_server_config.py
20:30
i ran ls -l ~/.jupyter/jupyter_server_config.py
20:52
i ran chmod 600 /home/jupyter/.jupyter/jupyter_server_config.py
20:59
i ran sudo systemctl restart jupyterlab
which failed becuase there’s no such password to run this command
23:56
ran exit
to change user from jupyter
to root
24:29
ran
printf 'Cmnd_Alias JLABCMDS = /bin/systemctl restart jupyterlab, /bin/systemctl status jupyterlab, /bin/systemctl stop jupyterlab, /bin/systemctl start jupyterlab\njupyter ALL=(root) NOPASSWD: JLABCMDS\n' > /etc/sudoers.d/jupyter-jupyterlab
chmod 440 /etc/sudoers.d/jupyter-jupyterlab
Timestamp
Notes
24:37
ran ls -l /etc/sudoers.d/jupyter-jupyterlab
24:43
ran cat /etc/sudoers.d/jupyter-jupyterlab
25:10
ran exit
can’t login to user jupyter
via PuTTy
26:37
logged in as root
26:52
ran install -d -m 700 -o jupyter -g jupyter /home/jupyter/.ssh
26:56
ran cp /root/.ssh/authorized_keys /home/jupyter/.ssh/authorized_keys
27:02
ran chown jupyter:jupyter /home/jupyter/.ssh/authorized_keys
27:07
ran chmod 600 /home/jupyter/.ssh/authorized_keys
27:13
ran ls -l /home/jupyter/.ssh/authorized_keys
27:25
logged out
27:58
logged in via SSH key as jupyter
28:05
ran sudo systemctl restart jupyterlab
which failed due to non-existant service unit
28:35
ran sudo tee /etc/systemd/system/jupyterlab.service >/dev/null <<'EOF'
[Unit]
Description=JupyterLab (proxied by Nginx)
After=network.target
[Service]
Type=simple
User=jupyter
Group=jupyter
WorkingDirectory=/home/jupyter
Environment="PATH=/home/jupyter/jlab-venv/bin:/usr/bin"
ExecStart=/home/jupyter/jlab-venv/bin/jupyter lab
Restart=on-failure
RestartSec=5
# Hardening
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=full
ProtectHome=true
[Install]
WantedBy=multi-user.target
EOF
Timestamp
Notes
32:33
ran systemctl daemon-reload
32:37
ran systemctl enable --now jupyterlab
32:43
ran systemctl status jupyterlab --no-pager
33:08
ran journalctl -u jupyterlab -e --no-pager
33:12
ran sudo -u jupyter /home/jupyter/jlab-venv/bin/jupyter --version
33:43
ran nano /etc/systemd/system/jupyterlab.service
33:53
replace a line to ExecStart=/home/jupyter/jlab-venv/bin/python3 -m jupyterlab --no-browser --config=/home/jupyter/.jupyter/jupyter_server_config.py
34:08
ran systemctl daemon-reload
34:13
systemctl restart jupyterlab
34:25
ran journalctl -u jupyterlab -e --no-pager
35:17
ran nano /etc/systemd/system/jupyterlab.service
35:27
grey-ed out ProtectHome
35:45
ran systemctl daemon-reload
35:49
ran systemctl restart jupyterlab
35:54
ran systemctl status jupyterlab --no-pager
36:24
ran apt update
36:34
ran apt install -y nginx certbot python3-certbot-nginx
36:45
ran ufw allow OpenSSH
36:52
ran ufw allow 'Nginx Full'
36:57
ran ufw enable
new putty session on root
user
37:36
ran tee /etc/nginx/sites-available/jupyterlab >/dev/null <<'EOF'
same as nano /etc/nginx/sites-available/jupyterlab
# Simple rate limit to protect /login from bots
limit_req_zone $binary_remote_addr zone=jrate:10m rate=10r/s;
server {
listen 80;
server_name lab.example.com;
# Security headers (added on HTTP too; Certbot will keep them on HTTPS)
add_header X-Frame-Options SAMEORIGIN;
add_header X-Content-Type-Options nosniff;
add_header Referrer-Policy strict-origin-when-cross-origin;
location / {
limit_req zone=jrate burst=20 nodelay;
proxy_pass http://127.0.0.1:8888;
proxy_http_version 1.1;
# Websocket + proxy headers Jupyter needs
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 64m;
proxy_read_timeout 600;
proxy_send_timeout 600;
}
}
Timestamp
Notes
40:21
ran ln -s /etc/nginx/sites-available/jupyterlab /etc/nginx/sites-enabled/jupyterlab
40:29
ran nginx -t && systemctl reload nginx
40:40
ran certbot --nginx -d lab.example.com --redirect -m you@example.com --agree-tos -n
41:25
ran certbot renew --dry-run
49:25
i show Jupyter Lab up and running with Let’s Encrypt HTTPS
Ethan1
September 28, 2025, 11:38am
2
Here’s a new (untested) set of commands that might lead to a more secure outcome;
Deployed the LTS option Ubuntu 24.04 x64
ssh root@<your_server_ip>
ufw allow http
ufw allow https
ufw allow ssh
ufw enable
adduser --disabled-password --gecos "" jupyter
usermod -aG sudo jupyter
su - jupyter
sudo apt update && sudo apt upgrade -y
exit
passwd jupyter
su - jupyter
sudo apt update && sudo apt upgrade -y
sudo apt install -y python3-pip python3-venv
python3 -m venv ~/jupyterlab-env
source ~/jupyterlab-env/bin/activate
pip install --upgrade pip jupyterlab
jupyter lab --generate-config
jupyter lab password
sudo nano /etc/systemd/system/jupyterlab.service
[Unit]
Description=JupyterLab
After=network.target
[Service]
Type=simple
User=jupyter
WorkingDirectory=/home/jupyter
Environment="PATH=/home/jupyter/jupyterlab-env/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin"
ExecStart=/home/jupyter/jupyterlab-env/bin/jupyter lab --no-browser --ip=127.0.0.1 --port=8888
Restart=on-failure
[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable jupyterlab
sudo systemctl start jupyterlab
sudo systemctl status jupyterlab
sudo apt install -y nginx
sudo nano /etc/nginx/sites-available/jupyterlab
server {
listen 80;
server_name lab.year2physics.site;
location / {
proxy_pass http://127.0.0.1:8888;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
# Increase the buffer size for large notebooks
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
sudo ln -s /etc/nginx/sites-available/jupyterlab /etc/nginx/sites-enabled/
sudo nginx -t
sudo systemctl reload nginx
sudo apt install -y certbot python3-certbot-nginx
sudo certbot --nginx -d lab.year2physics.site
sudo nano /etc/nginx/sites-available/jupyterlab
you may need to replace your config so Nginx preserves /lab
when proxying:
server {
listen 80;
server_name lab.year2physics.site;
return 301 https://$host$request_uri;
}
server {
listen 443 ssl;
server_name lab.year2physics.site;
ssl_certificate /etc/letsencrypt/live/lab.year2physics.site/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/lab.year2physics.site/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
client_max_body_size 64M;
# redirect root to /lab
location = / {
return 302 /lab;
}
# proxy all /lab routes
location /lab/ {
proxy_pass http://127.0.0.1:8888/lab/;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_buffer_size 128k;
proxy_buffers 4 256k;
proxy_busy_buffers_size 256k;
}
}
run sudo nano /home/jupyter/.jupyter/jupyter_server_config.json
then replace to, merging your password hash
{
"IdentityProvider": {
"hashed_password": "argon2:$argon2id$v=19$m=10240,t=10,p=8$Kucdq4m2c8qoTBbjRsP6Ig$rXB/oS24X2nWWlbGPYbxbQzoQAvlQj..."
},
"ServerApp": {
"ip": "127.0.0.1",
"port": 8888,
"open_browser": false,
"allow_remote_access": true,
"trust_xheaders": true,
"token": "",
"base_url": "/lab",
"allow_origin": "https://lab.year2physics.site",
"allow_credentials": true
}
}
run sudo systemctl restart jupyterlab
shoul;d be working now
1 Like