Skip to content

Instantly share code, notes, and snippets.

@ubergeek42
Last active April 20, 2022 17:03
Show Gist options
  • Save ubergeek42/1be710d8feca03a40004784d05443989 to your computer and use it in GitHub Desktop.
Save ubergeek42/1be710d8feca03a40004784d05443989 to your computer and use it in GitHub Desktop.
ICPC Proxied Network Access

ICPC Proxied Network Access

This is the method we've used at the ICPC SouthEast USA regional contest for years.

The basic idea:

  • Run squid as a proxy locally on each machine
  • Configure squid (using squidGuard) to only allow allow access to certain domains
    • Technically this can support specific URLs on a given domain, but I don't think that works with https
  • Configure UFW firewall to only allow network access through the proxy
  • Configure a local webserver to serve up a "block" page whenever a user tries to access something they shouldn't
<!doctype html>
<html class="no-js" lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<title></title>
<meta name="description" content="">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}</style>
<style>
/*! HTML5 Boilerplate v5.0 | MIT License | http://h5bp.com/ */
html {
color: #222;
font-size: 1em;
line-height: 1.4;
height: 100%;
}
body {
height: 100%;
}
::-moz-selection {
background: #b3d4fc;
text-shadow: none;
}
::selection {
background: #b3d4fc;
text-shadow: none;
}
hr {
display: block;
height: 1px;
border: 0;
border-top: 1px solid #ccc;
margin: 1em 0;
padding: 0;
}
#wrapper {
min-height:100%;
position: relative;
}
.banner {
width: 100%;
padding-top: 50px;
padding-bottom: 50px;
height: 90px;
margin: 0;
text-align: center;
background: #9B1111;
}
#content {
padding-bottom: 200px;
margin-left: auto;
margin-right: auto;
width: 750px;
}
h1 {
color: white;
}
</style>
</head>
<body>
<div id="wrapper">
<div class="banner"><h1>Access Denied</h1></div>
<div id="content">
<h3>The site you are trying to access cannot be displayed</h3>
<p>
During the programming contest general access to the internet is not provided or allowed.
You may only use the materials you brought with you for reference, plus any documentation available locally on this machine.</p>
<hr>
</div>
<div class="banner" style="position:absolute; bottom: 0px;"><h1>Access Denied</h1></div>
</div>
</body>
</html>
http_port 3128
dns_v4_first on
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access deny manager
http_access allow all
shutdown_lifetime 1 second
coredump_dir /var/spool/squid
url_rewrite_program /usr/bin/squidGuard -c /etc/squidguard/squidGuard.conf
dbhome /var/lib/squidguard/db
logdir /var/log/squidguard
dest icpcsites {
domainlist icpcsites-domainlist
urllist icpcsites-urllist
}
acl {
default {
pass icpcsites none
redirect http://localhost/block.html
}
}
allowed_domains:
- somecontest.kattis.com
# kattis has a bunch of external dependencies it talks to...
- cdnjs.cloudflare.com
- cdn.jsdelivr.net
- ajax.googleapis.com
- fonts.gstatic.com
- licensebuttons.net
allowed_urls: []
---
- name: install local squid proxy + squidguard
apt:
state: present
pkg:
- squid3
- squidguard
- name: configure squidguard
copy: src=files/squid/squidGuard.conf dest=/etc/squidguard/squidGuard.conf
- name: template out the allowed domains
copy:
dest: /var/lib/squidguard/db/icpcsites-domainlist
content: |
{% for x in allowed_domains %}
{{x}}
{% endfor %}
- name: template out the allowed urls
copy:
dest: /var/lib/squidguard/db/icpcsites-urllist
content: |
{% for x in allowed_urls %}
{{x}}
{% endfor %}
- name: configure squid
copy: src=files/squid/squid.conf dest=/etc/squid/squid.conf
notify: restart squid
- name: configure system to use the proxy by default
lineinfile: dest=/etc/environment line="{{item}}"
with_items:
- http_proxy="http://localhost:3128/"
- https_proxy="http://localhost:3128/"
- ftp_proxy="http://localhost:3128/"
- no_proxy="localhost,127.0.0.1"
- HTTP_PROXY="http://localhost:3128/"
- HTTPS_PROXY="http://localhost:3128/"
- FTP_PROXY="http://localhost:3128/"
- NO_PROXY="localhost,127.0.0.1"
- name: Make sure inbound policy is deny
ufw: direction=incoming policy=deny
- name: allow inbound ssh
ufw: rule=allow name=OpenSSH
- name: enable the firewall
ufw: state=enabled logging=off
- name: prevent the 'contestant' user from using the network(except through the proxy or to localhost)
lineinfile: dest=/etc/ufw/before.rules line="-I ufw-before-output -m owner --uid-owner contestant -j REJECT" insertbefore="^# don't delete the 'COMMIT' line" state=present
- name: Allow the contestant user(and others) to talk to localhost from localhost). Fixes issue with intellij/eclipse compilation/debugging.
lineinfile: dest=/etc/ufw/before.rules line="-I ufw-before-output -s 127.0.0.1 -d 127.0.0.1 -j ACCEPT" insertafter="uid-owner contestant -j REJECT" state=present
- name: copy block page for squid to use
template: src=files/squid/block.html.j2 dest=/opt/localwww/block.html
---
# This is a simple webserver (mostly to serve up the squid block page)
- name: make sure web dir exists
file: state=directory path=/opt/localwww
- name: make sure busybox is installed(we're using its webserver)
apt: pkg=busybox state=present
- name: add simple-httpd init script
copy:
dest: /etc/systemd/system/simple-httpd.service
content: |
[Unit]
Description=Simple web server for documentation
After=network.target
[Service]
ExecStart=/bin/busybox httpd -u www-data -p 80 -h /opt/localwww -f
[Install]
WantedBy=multi-user.target
notify: restart simple-httpd
- name: enable simple-httpd service
service: name=simple-httpd enabled=yes
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment