A post talking about combining ThinLinc (a truly amazing Linux based remote access solution), Fortinet FortiWeb and nginx as a reverse proxy.
The idea is relatively simple, I wanted to host a ThinLinc Web Access remote access possibility although through different possible ingressing sides. In fact, I needed to be able to hook on the tlwebaccess
service from within my local networks while still having the same possibility although through public networks.
To complexify a bit, I wanted the public access to be achieved over an existing FQDN and using a dedicated /thinlinc
path.
Here is an high level view of the wanted setup:

Let's start with the ThinLinc Server setup, you'll find all the needed documentation here: https://www.cendio.com/resources/docs/tag/
I've done the following modifications on my local setup once installed:
/opt/thinlinc/etc/conf.d/webaccess.hconf:
- TCP:443 as it's bound port
- Added both the locally trusted server.crt/.key
/opt/thinlinc/etc/conf.d/vsmagent.hconf:
- agent_hostname=local.host.name (FQDN.local type of hostname)
The agent_hostname is used by ThinLinc in order to redirect any successfully authenticated user to the final ThinLinc destination while opening the connection. We will see further on why this might give some issues in the wanted setup.
Onto the nginx setup, all I wanted was a reverse proxy listening on a dedicated TCP port and handling some rewriting. Here is my setup:
pyjaman@tlhost:~$ cat /etc/nginx/nginx.conf
...
http {
...
include /etc/nginx/conf.d/*.conf;
}
pyjaman@tlhost:~$
pyjaman@tlhost:~$ cat /etc/nginx/conf.d/nginx-ssl.conf
server {
listen 4443 ssl http2;
server_name localhost;
ssl_certificate /etc/ssl/server.crt;
ssl_certificate_key /etc/ssl/server.key;
ssl_protocols TLSv1.2;
ssl_ciphers HIGH:!aNULL:!MD5;
location /thinlinc/ {
proxy_pass https://10.1.1.253:443/;
proxy_redirect /main/ /thinlinc/main/;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Ssl on;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_cookie_path / /thinlinc/;
proxy_read_timeout 36000;
proxy_send_timeout 36000;
sub_filter ="/ ="/thinlinc/;
sub_filter tlhost.local:443/agent public.fqdn.ch:443/thinlinc/agent;
sub_filter 10.1.1.253 $host;
sub_filter websocket/ thinlinc/websocket/;
sub_filter_once off;
}
}
The above nginx reverse proxy setup will; make the service available on the wanted /thinlinc
path as well as rewrite the ThinLinc sent "agent_hostname" with our wanted publicly reachable FQDN.
I took here inspirations on two distinct blog posts:
https://www.verboom.net/blog/index.html?single=20151019.0
https://www.bitbull.ch/wiki/index.php/Thinlinc_html5_webaccess_behind_nginx_reverse_proxy
After which, once both ThinLinc Web Access and the nginx reverse proxy are started, they shall bind TCP:443 as well as TCP:4443 on our ThinLinc host:
pyjaman@tlhost:~$ sudo ss -tnlp | grep 443
LISTEN 0 511 0.0.0.0:4443 0.0.0.0:* users:(("nginx",pid=413,fd=5),("nginx",pid=412,fd=5),("nginx",pid=411,fd=5))
LISTEN 0 128 *:443 *:* users:(("python3",pid=432,fd=3))
Therefore, we shall be able to reach our TCP:443 internally, being redirected by ThinLinc toward the correct host – bizznizz as usual here. This while also being able to address our TCP:4443 nginx reverse proxy from the outside world through FortiWeb in my case, pretty neat.
I'll be assuming that FortiWeb is already in place, configured and able to possibly address back-end authentications systems, in my case a FortiAuthenticator appliance enabling PCI DSS 3.2 two-factor authentication.
In my setup, what was needed were a couple of items on FortiWeb; an HTTP Content Routing Policy, a Server Pool entry, a dedicated Web Protection Profile, a Site Publishing Policy and obviously the wanted authentication schemes you want to address, the GeoIP you want, host-name protection etc etc.



This will provide us with the possibility to address our ThinLinc enabled system from the Internet while leveraging Fortinet based multi-factor authentications. Here is a view of the user experience from the Internet:




This while of course, HTTPS connection towards TCP:443 if addressing the ThinLinc host from our internal networks will provide the same results although without 2FA and thus reaching directly on the ThinLinc service.
Hope you've enjoyed this post, have a check at ThinLinc it's really a neat piece of software and so is FortiWeb.
Cheers,
Obuno
Image Credits: Eric Gagnon - https://www.artstation.com/artwork/8l9VGw