ref: b112d069bdf00e6f983bc88349aef355a573cae3 krasovs.ky/content/blog/checkpoint-snx-adventure.md -rw-r--r-- 8.2 KiB
b112d069Savely Krasovsky fix(telegram-web-apps): title fix 5 months ago

#date: 2021-04-26 title: "Checkpoint SNX adventure: isolating the proprietary in it own box" layout: post

My company uses Checkpoint products as a VPN solution. In case of Windows and macOS there is Checkpoint Endpoint Security. In case of Linux we have to use whatever called Checkpoint SSL Network Extender or just Checkpoint SNX.

As far as I got, it encapsulates traffic into HTTPS connection between you and VPN gateway and provides TUN interface. Sounds okay on paper, right?

But as you know, proprietary software has something in common: the quality of Linux support generally sucks. Checkpoint SNX is not an exception.

Just read their support page. The distros they consider relevant in 2021: Ubuntu 17.04, Fedora 18, openSUSE 12.2. Okay, cool.

The shitty quality of Linux solution itself wasn't the main reason to isolate it. Gateways like this are pushing settings from the server including routes, usually there is no way to somehow reconfigure this.

In my case, the company decided that split tunneling isn't secure. It means while I am connected and trying to reach corporate resources, I cannot reach the Internet without corporate proxy and vice versa.

So I had an idea: it would be nice to just share Checkpoint VPN connection with other computers.

Particularly I wanted to:

  1. Completely isolate Checkpoint SNX inside Linux VM.
  2. Use WireGuard tunnels to share VPN connection.
  3. At client-side use only one simple route:

Why WireGuard? I could just use IP forwarding and NAT tweaks, but it would only work within a particular LAN and I would have to create and delete route and change DNS servers every time manually.

Let's get started.

#Install Checkpoint SNX

You can download SNX installer from your company's VPN portal:

$ curl https://example.org/SNX/INSTALL/snx_install.sh -o snx_install.sh
# OR
$ curl https://example.org/sslvpn/SNX/INSTALL/snx_install.sh -o snx_install.sh

There is also a way to install the latest version from Checkpoint site, but I don't recommend it, your company could use different version.

While the first part of script is just a bash script, the second part contains an archive with the binaries. The binaries are x86 (not x86-64), so you need to enable multiarch and install dependencies.

# ldd /usr/bin/snx
    libX11.so.6 => /usr/lib32/libX11.so.6
    libpam.so.0 => /usr/lib32/libpam.so.0 (0xf7d3d000)
    libstdc++.so.5 => /usr/lib32/libstdc++.so.5 (0xf7c5c000)

So you need to install three libraries: libX11, libpam, libstdc++. In various distros you need to use various names, but you can easily google it.

Finally, just install it:

$ chmod +x snx_install.sh
$ sudo ./snx_install.sh

Back to your browser and try to connect using the portal. A while back you needed a browser that supports NPAPI to launch Java-applet, but currently it seems like Checkpoint SNX uses the new mechanism. That's why most probably a webpage will ask you to install whatever called cshell, but not csh, you will have to download another script cshell_install.sh.


Before installation install OpenJRE, in my case only the latest 15.0 worked well.

$ chmod +x cshell_install.sh
$ sudo ./cshell_install.sh

In case of any errors probably you have a wrong OpenJRE version. Fortunately you can test it even after failed installation process:

$ java -jar /usr/bin/cshell/CShell.jar


Scrips are idempotent, so you can run them indefinitely until getting a fix

After successful installation of snx and cshell there is another step: this jar-file runs HTTPS-server at localhost:14186, but installer fails to make certificate trusted. There are two ways to fix it:

  • Add /usr/bin/cshell/cert/CShell_Certificate.crt as trusted (preferred)
  • Just go to the localhost:14186 in your favourite browser and mark it as trusted.

Now try to reconnect again. Everything should now work.

#WireGuard tunnel

I don't want to tell here how WireGuard works. I will just provide an example of working configs:

Peer A (VM with SNX):

PrivateKey = ... # ABC
ListenPort = 51820
Address =

# Host PC
PublicKey = ... # XYZ' public key
AllowedIPs =

# You add here another peers:
# Mobile phone
# [Peer]
# PublicKey = DEF
# AllowedIPs =

Peer B (PC with which I want to share):

PrivateKey = ... # XYZ
Address =
DNS = DNS1, DNS2 # found out you VPN DNS server and hard code them here

PublicKey = ... # ABC's public key
AllowedIPs =
Endpoint = # Use an IP of your bridged VM

On both sides enable peers. You can test tunnel simply pinging thought it:

# from device to VM with SNX
$ ping


Of course without proper firewall setup, an SNX connection won't share. I will use modern nftables.


#!/usr/bin/nft -f
# ipv4/ipv6 Simple & Safe Firewall
# you can find examples in /usr/share/nftables/

flush ruleset

table inet filter {
	chain input {
		type filter hook input priority 0; policy drop;

		# allow established/related connections
		ct state {established, related} accept

		# early drop of invalid connections
		ct state invalid drop

		# allow from loopback
		iifname lo accept

		# allow icmp
		ip protocol icmp accept
		meta l4proto ipv6-icmp accept

		# allow wireguard
		udp dport 51820 accept

		# everything else
		reject with icmpx type port-unreachable

	chain forward {
		type filter hook forward priority 0; policy drop;

		ct state {established, related} accept
		ct state invalid drop

		# allow forwarding from wireguard interface to snx one
		iifname wg0 oifname tunsnx ct state new accept

	chain output {
		type filter hook output priority 0; policy accept;

table inet nat {
	chain postrouting {
		type nat hook postrouting priority srcnat;


Don't forget to enable IP forwarding:



To share SNX connection you will have to configure SNAT dynamically after connection (and disconnection). I will use systemd oneshot-service to do this.


Description=Checkpoint SNX firewall tweaker



The mix of BindsTo and RemainsAfterExit allows us to trigger ExecStart and ExecStop at the right time, when connection starts and when connection stops.

As you could see above, service also requires two scripts:



GATEWAY=$(ip -o -4 addr show tunsnx | awk '{printf $4}')
nft add rule inet nat postrouting oifname "tunsnx" ip daddr snat ip to $GATEWAY
echo "nftables rule added"



nft flush chain inet nat postrouting
echo "nftables flushed"

This is where all the magic is going on. Simple masquerading doesn't help in this case. Reconnect you SNX and try to open corporate resource. Works? Cool!

Feel free to leave comments below the post.

UPDATE: I can also recommend removing default cshell autostart (from ~/.config/autostart/cshell.desktop) because it's not reliable and setup user systemd service:

Description=Checkpoint SNX CShell

# Should work for JRE 16+
ExecStart=/usr/bin/java --add-exports java.base/sun.net.spi=ALL-UNNAMED -jar CShell.jar /tmp/cshell.fifo
ExecStop=/bin/kill -15 $MAINPID


UPDATE 2: Rui Ribeiro from comments suggested much nicer method using chroot, check it!