Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add code back in #547

Merged
merged 3 commits into from
Dec 10, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions DEVELOPER.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,23 @@
# Developer instructions

## Production deployments

### Environment variables

It's important to set `DUO_ENV=prod`.

### Proxies

Note also that `X-Forwarded-For` headers are treated as the user's real IP by
Duolicious, which assumes that there's a proxy between it and users.

If there's no proxy, `X-Forwarded-For` headers can be spoofed by users. This
will allow malicious users to partially bypass rate limits and bans.

Whether `X-Forwarded-For` is used or not should probably be configurable in
Duolicious, but it's currently not. Although hardcoding the solution isn't too
hard: Simply remove the use of `werkzeug.middleware.proxy_fix.ProxyFix`.
Copy link
Member Author

@duogenesis duogenesis Dec 10, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I raised a ticket to make this configurable: #548


## Running the tests

Install these:
Expand Down
2 changes: 2 additions & 0 deletions service/application/decorators.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import duotypes
import os
from pathlib import Path
from werkzeug.middleware.proxy_fix import ProxyFix
import ipaddress
import traceback
from antispam import normalize_email
Expand Down Expand Up @@ -65,6 +66,7 @@ def _get_remote_address() -> str:
CORS_ORIGINS = os.environ.get('DUO_CORS_ORIGINS', '*')

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_for=1)
app.config['MAX_CONTENT_LENGTH'] = constants.MAX_CONTENT_LENGTH;

default_limits = "60 per minute; 12 per second"
Expand Down
164 changes: 52 additions & 112 deletions vm/nginx/duolicious.conf
Original file line number Diff line number Diff line change
Expand Up @@ -20,40 +20,20 @@ upstream chat_backend {
server localhost:5445;
server localhost:5446;

# server localhost:5447;
# server localhost:5448;
# server localhost:5449;
# server localhost:5450;

# server localhost:5451;
# server localhost:5452;
# server localhost:5453;
# server localhost:5454;

# server localhost:5455;
# server localhost:5456;
# server localhost:5457;
# server localhost:5458;

# server localhost:5459;
# server localhost:5460;
# server localhost:5461;
# server localhost:5462;

# server localhost:5463;
# server localhost:5464;
# server localhost:5465;
# server localhost:5466;

# server localhost:5467;
# server localhost:5468;
# server localhost:5469;
# server localhost:5470;

# server localhost:5471;
# server localhost:5472;
# server localhost:5473;
# server localhost:5474;
server localhost:5447;
server localhost:5448;
server localhost:5449;
server localhost:5450;

server localhost:5451;
server localhost:5452;
server localhost:5453;
server localhost:5454;

server localhost:5455;
server localhost:5456;
server localhost:5457;
server localhost:5458;
}

server {
Expand All @@ -70,28 +50,29 @@ server {
client_max_body_size 20M;
client_body_buffer_size 128k;

# Cloudflare IP ranges
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;

deny all;
# Mark Cloudflare proxies as trusted
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;

# Use the header Cloudflare sets to pass the original client IP
real_ip_header CF-Connecting-IP;

# If multiple proxies are involved, recursively resolve the real IP
real_ip_recursive on;

location / {
proxy_pass http://api_backend;

Expand Down Expand Up @@ -121,41 +102,35 @@ server {
proxy_cache_bypass $http_upgrade;
}

# listen 443 ssl; # managed by Certbot
# listen [::]:443 ssl; # managed by Certbot
# ssl_certificate /etc/letsencrypt/live/api.duolicious.app/fullchain.pem; # managed by Certbot
# ssl_certificate_key /etc/letsencrypt/live/api.duolicious.app/privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

# Configuration for chat.duolicious.app
server {
server_name chat.duolicious.app;

# Cloudflare IP ranges
allow 173.245.48.0/20;
allow 103.21.244.0/22;
allow 103.22.200.0/22;
allow 103.31.4.0/22;
allow 141.101.64.0/18;
allow 108.162.192.0/18;
allow 190.93.240.0/20;
allow 188.114.96.0/20;
allow 197.234.240.0/22;
allow 198.41.128.0/17;
allow 162.158.0.0/15;
allow 104.16.0.0/13;
allow 104.24.0.0/14;
allow 172.64.0.0/13;
allow 131.0.72.0/22;

deny all;
# Mark Cloudflare proxies as trusted
set_real_ip_from 173.245.48.0/20;
set_real_ip_from 103.21.244.0/22;
set_real_ip_from 103.22.200.0/22;
set_real_ip_from 103.31.4.0/22;
set_real_ip_from 141.101.64.0/18;
set_real_ip_from 108.162.192.0/18;
set_real_ip_from 190.93.240.0/20;
set_real_ip_from 188.114.96.0/20;
set_real_ip_from 197.234.240.0/22;
set_real_ip_from 198.41.128.0/17;
set_real_ip_from 162.158.0.0/15;
set_real_ip_from 104.16.0.0/13;
set_real_ip_from 104.24.0.0/14;
set_real_ip_from 172.64.0.0/13;
set_real_ip_from 131.0.72.0/22;

# Use the header Cloudflare sets to pass the original client IP
real_ip_header CF-Connecting-IP;

# If multiple proxies are involved, recursively resolve the real IP
real_ip_recursive on;

location / {
proxy_pass http://chat_backend;

Expand All @@ -166,39 +141,4 @@ server {

}

# listen 443 ssl; # managed by Certbot
# listen [::]:443 ssl; # managed by Certbot
# ssl_certificate /etc/letsencrypt/live/api.duolicious.app/fullchain.pem; # managed by Certbot
# ssl_certificate_key /etc/letsencrypt/live/api.duolicious.app/privkey.pem; # managed by Certbot
# include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
# ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot

}

# server {
# if ($host = api.duolicious.app) {
# return 301 https://$host$request_uri;
# } # managed by Certbot
#
#
# listen 80;
# listen [::]:80;
# server_name api.duolicious.app;
# return 404; # managed by Certbot
#
#
# }
# server {
# if ($host = chat.duolicious.app) {
# return 301 https://$host$request_uri;
# } # managed by Certbot
#
#
# listen 80;
# listen [::]:80;
# server_name chat.duolicious.app;
# return 404; # managed by Certbot
#
#
#
# }
Loading