Tunnels on Subdomains
Starting with rport version 0.9.5 you can access http-based tunnels on subdomains.
This feature was introduced to comply with strict firewall rules that block outgoing connections to none-default ports. After a tunnel has been created you access it on a random port according to the port range reserved for tunnels. With the new feature an additional random subdomain is created typically on port 443 as an alternative way to access the tunnel.
That means you can access a tunnel on https://rport.example.com:34567
or on https://pio0toazivaeGheif2.tunnels.example.com
Subdomains can be created for http(s) based tunnels such as RDP or VNC via browser or remote web-uis. SSH over web is currently not supported.
For the subdomain to tunnel routing rportd uses caddy as reverse-proxy. Starting, stopping and configuring the caddy server is entirely done by rportd. No manual caddy configuration is needed.
You must have caddy installed on the same host with rportd. Using caddy inside a separated docker container is not supported. Rportd takes full control over caddy and the communication is handled over a unix socket.
Either install caddy manually by just downloading it
sudo curl -L "https://caddyserver.com/api/download?os=linux&arch=amd64" -o /usr/local/bin/caddy
sudo chmod +x /usr/local/bin/caddy
or install via package manager. This way you make sure you get caddy updates together with OS updates.
Once installed execute
sudo setcap 'cap_net_bind_service=+ep' $(which caddy)
Allow privileged port binding
Because eitherrportd
norcaddy
run with root privileges, by default caddy cannot bind to port 443 or any port below 1024. You must explicitly allow this by executingsudo setcap 'cap_net_bind_service=+ep' $(which caddy)
. If the commandsetcap
is not available, install withsudo apt-get install libcap2-bin
.Disable caddy systemd unit
When installing caddy via package manager, caddy will start automatically on system start. This might conflict with caddy being run as subprocess from rportd. You would be well advised to switch caddy systemd autostart off withsystemctl disable caddy
To make the random subdomain available you must create a wildcard DNS record. This is usually done by entering *.
as
prefix for a subdomain. For example, if you want to use *.tunnels.example.com
you must create a new host *.tunnels
for the domain example.com
. Using the API and UI inside the range of the wildcard is supported, for example *.example.com
for the tunnel subdomains, and rport.example.com
. In such case the second DNS record is not needed.
For the dynamic creation of the subdomains you need a wildcard SSL certificate that covers the DNS record. You can buy a commercial certificate or use Let’s encrypt. For the latter you must confirm your ownership of the domain by a DNS record. Look at the example below:
certbot certonly --manual --preferred-challenges dns -d *.tunnels.example.com
Before executing the above command, make sure you are logged in to the admin panel of your DNS.
The command will display a DNS text record you must create, and then it waits for your confirmation.
Before continuing open a new terminal and make sure your DNS TXT record has become available using for example dig
:
dig -t txt _acme-challenge.tunnels.example.com
If your record is listed as indicated by certbot, continue.
Doublecheck your certificate is a wildcard certificate with:
openssl x509 -noout -subject -in /etc/letsencrypt/live/<YOUR-DOMAIN>/fullchain.pem
Make sure the rport
user has read-rights on the certificate and key file. By default, Let’s encrypt creates files
readable just for root. Consider giving read access to anyone or create a user group.
find /etc/letsencrypt/archive/ -type d -exec chmod o+rx {} \;
find /etc/letsencrypt/archive/ -type f -exec chmod o+r {} \;
find /etc/letsencrypt/live/ -type d -exec chmod o+rx {} \;
find /etc/letsencrypt/live/ -type f -exec chmod o+r {} \;
For the configuration of the caddy integration you have two options.
- split port setup: The rportd-API/UI and the subdomains will listen on different TCP ports. Subdomains will typically use 443, and the API/UI any other free port, e.g. 8443. Caddy will route subdomains only, the API/UI has its independent built-in web server.
- shared port setup: The rportd-API/UI and the subdomains will listen on the same TCP port, typically 443. Caddy will route all http connection. The built-in API/UI web server acts as a backend behind the reverse proxy.
For any kind of setup, add a configuration like this to your /etc/rport/rportd.conf
file.
[caddy-integration]
## Enable https tunnels on random subdomains.
## See https://docs.rport.io/advanced/tunnels-on-subdomains/
## Note: no defaults currently.
## Specifies the path to the caddy executable. mandatory.
# caddy="/usr/bin/caddy"
## The bind address where caddy should listen for subdomain tunnels connections. mandatory.
# address="0.0.0.0:8443"
## All caddy subdomain tunnels will have the domain prefix listed below. mandatory.
# subdomain_prefix="tunnels.example.com"
## An SSL wildcard certificate is required that matches the subdomain prefix above. mandatory.
# cert_file="/etc/letsencrypt/live/<YOUR-DOMAIN>/fullchain.pem"
# key_file="/etc/letsencrypt/live/<YOUR-DOMAIN>/privkey.pem"
- For the
subdomain_prefix
do not enter the*
sign. If your DNS record is*.rport.example.com
enterrport.example.com
. - Make sure the port of the
address
does not conflict with the port of the address in the[api]
section.
If you want to run the subdomains managed by caddy and the rport API/UI on different TCP ports, you can stop here and restart rportd.
Additionally, to the above setting, add the following lines to the [caddy-integration]
block.
## If you want to run the API and the tunnel subdomains on the same HTTPs port,
## you must specify a hostname for the API.
api_hostname = "rport-api.example.com"
## Even if the above api_hostname is inside the validity of the above certificate,
## you must specify wich certificate to use for the API.
api_cert_file = "/etc/ssl/certs/rport/api.crt"
api_key_file = "/etc/ssl/certs/rport/api.key"
## Port of the API with TLS switched off. Port must match the port of "[api] address"
api_port = "3000"
The address
on the [api]
must match the api_port
on the [caddy-integration]
section.
Also, the api must have SSL/TLS switched off, by commenting out the paths to the key and certificate.
For the above example the corresponding [api]
config is:
[api]
## Defines the IP address and port the API server listens on.
## Specify non-empty {address} to enable API support.
address = "0.0.0.0:3000"
## <snip snap>
## If both cert_file and key_file are specified, then rportd will use them to serve the API with https.
## Intermediate certificates should be included in cert_file if required.
#cert_file = "/etc/letsencrypt/live/rport/fullchain.pem"
#key_file = "/etc/letsencrypt/live/rport/privkey.pem"
If you change the hostname of your rport server in therportd.conf
file you very likely must change it in the email-based two-factor sender script too. Check/usr/local/bin/2fa-sender.sh
.
If rport doesn’t start with the new configuration, inspect the start errors with
journalctl -u rportd.service --no-pager -e
Also, look at
/var/log/rport/rportd.log
.Consider increasing the
log_level
todebug
in the/etc/rport/rportd.conf
file.To query the current caddy routing and the active subdomains, use:
curl http://localhost/config/apps/http/servers/srv0/routes \ --unix-socket /var/lib/rport/caddy-admin.sock -H "host:unix"|jq
- Create a tunnel for RDP and activate “Enable RDP via browser” or
- Create a tunnel for VNC and select “Enable NoVNC (VNC via Browser)” or
- Create a tunnel for HTTP/HTTPs and activate “Enable HTTP Reverse proxy”
All the above tunnel settings will trigger the creation of a subdomain. After tunnel creation you will notice that the
API returns a field tunnel_url
. The “access tunnel” button of the UI will point to that URL instead of pointing to the
random port on the main domain of the rport server.