In this lab, we will deploy and test Pfsense's functionalities, using VMWare Pro 16 to simulate our network model.
- Pfsense Lab Deployment
- Setup:
- Basic rules:
- 0. Intro:
- 1. Block local network (192.168.3.0/24-VM-B) ping to VM-A
- 2. Block local network (192.168.3.0/24-VM-B) from accessing website using port 80 (HTTP)
- 3. Block local network (192.168.3.0/24-VM-B) telnet to other areas
- 4. Block local network (192.168.3.0/24-VM-B) from accessing facebook.com and youtube.com
- Bypass Firewall by SSH Tunnel:
- 1. Telnet to VM-A by SSH Tunnel
- 2. How is it possible? Was the packet go through the firewall ? Why did the firewall use this tunnel ? Please explain for me as detail as possible ?
- 3. Connect to facebook.com by SSH Tunnel with Proxy configuration
- 4. Remove SSH Tunnel, clear Cache data on browser. Connect to facebook.com again.
- 5. If on Firewall, we block SSH (port 22). Can we still create tunnel ?
- Web Proxy Deployment (Application Firewall)
- 0. Basic config
- 1. Establish redirection URL
- 2. Re-edit Perl code above with condition: when accessing "http://example.com", an blocking-warn image floats in.
- VPN
- Backup & Restore (Optional):
Network Card | Type | Subnet IP | Subnet mask | NAT Gateway |
---|---|---|---|---|
VMnet1 | Host-only | 192.168.3.0 | 255.255.255.0 | N/A |
VMnet8 | NAT | 10.0.3.0 | 255.255.255.0 | 10.0.3.2 |
On VMware
- Go to "Edit" --> "Virtual Network Editor" --> "Change Settings" to edit configuration
- In NAT card, go to "NAT Settings", check the "IP Gateway". This IP will let you connect to the Internet, so remember it! In my case is
10.0.3.2
Host | VM username | OS image | IP config | Description |
---|---|---|---|---|
VM-A | vma | Ubuntu Desktop 18.04 | NAT: 10.0.3.3/24 (static) Gateway: 10.0.3.2 DNS: 8.8.8.8 |
Using NAT to access to the Internet, plays role as intermediary to allow VM-B to surf websites and Internet services |
VM- B | vmb | Ubuntu Desktop 18.04 | Host-Only: 192.168.3.3/24 (static) Gateway: 192.168.3.2 |
Local PC as guest, access web via VM-A |
pfSense | N/A | pfSense Community Edition (AMD64) | - NAT: 10.0.3.4/24 (static) Gateway: 10.0.3.2 - Host-Only: 192.168.3.2/24 (static) Gateway: N/A |
Protect VM-B by making proper rules and policies |
Set static IP for host Ubuntu:
- Click on the network icon on the upper right corner => "Wired Connected" => "Wired Setting"
- In "Wired", click on setting icon
- Switch to "IPv4" tab, choose "Manual", fill in the necessary configurations based on above table
- Edit
/etc/netplan/01-network-manager-all.yaml
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager
ethernets:
<YOUR_INTERFACE>:
dhcp4: no
addresses: [<YOUR_IP>/<YOUR_SUBNET_NUMBER>]
gateway4: <YOUR_GATEWAY>
nameservers:
addresses: [1.1.1.1, 1.0.0.1, 8.8.8.8, 8.8.4.4]
For example, mine is:
# Let NetworkManager manage all devices on this system
network:
version: 2
renderer: NetworkManager
ethernets:
ens33:
dhcp4: no
addresses: [10.0.3.4/24]
gateway4: 10.0.3.2
nameservers:
addresses: [1.1.1.1, 1.0.0.1, 8.8.8.8, 8.8.4.4]
- Then execute
sudo netplan apply
- Reboot the computer (Any changes to network require this)
Install pfsense:
- Download image from the https://www.pfsense.org/download/. Choose the suitable version
- Set up with default settings while installing
- Manually set up interfaces (pfsense will auto-detect the LAN/WAN card after new installation):
- Choose option
1
, "Assign Interfaces" -> VLAN setting:No
-> Pick the right interfaces according to the MAC address: On VMware, click "VM" -> "Settings" -> Click on "Network Adapter" of NAT/Host-Only to inspect -> "Advanced" -> Check the MAC address - Choose option
2
for more configurations. Select the interface to configure:- WAN: Input IPv4 address, subnet mask(24), upstream gateway as above table, IPv6:
No
, DHCP:No
, reverting HTTP:No
. - LAN: like WAN, but nothing for upstream gateway.
- WAN: Input IPv4 address, subnet mask(24), upstream gateway as above table, IPv6:
- Choose option
5
to reboot - Done !!!
- Choose option
Check and test(3 VMs are up):
- You're able to ping between hosts VM-A <--> VM-B
- Both VMs can access to the internet
- Both VMs and your real host can access to Pfsense site: http://192.168.3.2/
Note: pfSense also acts as a Router. So routing from
VM-B
to the Internet is available if you configure correctly throughVM-A
. This makes me little confused at the very beginning too :))
Access to http://192.168.3.2/ for basic config on pfSense(user: admin
; password pfsense
). Fields that needs to be configured:
- Hostname:
pfsense
(your choice) - Domain:
localdomain
(your choice) - Primary DNS Server:
8.8.8.8
- Secondary DNS Server:
8.8.4.4
- Timezone:
Asia/Ho Chi Minh
(Your timezone) - In Configure WAN interface
- Selected Type:
DHCP
- Static IP Configuration: <As the same as above for WAN>
- RFC 1918 Private Network: Uncheck Block RFC1918 private networks
- Selected Type:
- In Configure LAN interface: <As the same as above for LAN>
- Reset the password as you like
- Finished !!!
All rules:
Note 1:
Block
would drop all the packets that matches the rules, this often make command's output produce nothing. WhileReject
will return an error message and the guest machine receive it clearly, this brings a friendlier experience to user
Note 2: Rule will be applied from top of the list til below.
Note 3: When blocking by specifying ports of a specific service/protocol, always use
Destination port
. TheSource port
is often randomly created by the OS and therefore, has no reason to be used :>
Rule:
- "Save" and then "Apply Changes". Result:
Rule:
Result:
We're able to access other website using HTTPS
, FTP
, ... Example: facebook.com
uses HTTPS
. But connecting to NeverSSL is forbidden as it use HTTP
List of No-SSL websites for testing: Whynohttps
- Make sure
VM-A
have already installed Telnet:sudo apt-get install telnetd
- Initialize the service:
sudo systemctl restart inetd
Try telnet from VM-B
to VM-A
:
All good! Now creating the rule:
Disconnect the current telent session by exit
. Try to make new telnet connection. Result:
4.1 Approach 1: Creating list of aliases
-
Method 1:
-
Method 2:
- Use
ping
command to get the public IP.ping
with multiple times to try to get difference IP. For example:
- Use
- Then import these IPs. We have no time to get as many IPs as possible. There is a "cheat" way once we've got the very first IP. For example, in this case we have IP
157.240.199.35
. So we wrap it up in a subnet mask, choose a little bit wide enough like/16
.
<p align="center">
<img height="300" width="750" src="images/alias_facebook_youtube_subnet.png" alt="pfsense-logo">
"Apply Changes" for Alias. Create rule:
Both methods generate the same result. We can't use facebook.com
or youtube.com
for entertainment purpose now :'((
4.2 Approach 2: Use DNS Resolver
<To be updated>
Make sure we installed ssh server
and telnetd
(above) in VM-A
sudo apt-get install openssh-server
sudo systemctl restart ssh
Creating a SSH Tunnel from VM-B
. Enter password for vma
:
ssh -fN -L 8000:localhost:23 [email protected]
This command creates an SSH tunnel that forwards local port 8000
to port 23
on the remote host localhost at IP address 10.0.3.3
, using the username ubuntu. The -f and -N flags run the process in the background and prevent the execution of a remote command, respectively.
You can verify the tunnel by:
sshd
is default when starting the ssh service, owned by root
. The three remainings that belong to user vmb
are what we've just created.
(Optional) We can remove this tunnel by kill the process with its process ID. For example, in this case, we use sudo kill -9 6028
Explain all flags:
f
: Requests ssh to go to background just before command execution.N
: Do not execute a remote command. This is useful for just forwarding ports.L
: Specifies that the given port on the local (client) host is to be forwarded to the given host and port on the remote side. In this case, port 8000 on the local machine will be forwarded to port 23 on the remote host localhost at IP address 10.0.3.3.
Now, we try to use telnet to the bind host localhost <----> [email protected]
with the above bind port 8000 <---> 23
. Remember to enable rule "Block telnet" above.
We've bypassed the firewall ^w^
. Here are some questions:
2. How is it possible? Was the packet go through the firewall ? Why did the firewall use this tunnel ? Please explain for me as detail as possible ?
First, Yes, the packets would go through the firewall but with a different port number, in this case port 8000
. The firewall rule is blocking Telnet connections on port 23
, but the SSH tunnel is using a different port 8000
for the connection, so the packets are not being blocked by the firewall.
Then, what happened next? Well, after go through port 8000
, our packets will be forwarded to port 23
, right? That's when the magic appears, I means, ... the SSH mechanism :0 ... When you connect to the local port 8000
, the connection is forwarded over the encrypted SSH connection to the remote host, this makes the pfsense firewall could not figure out the port 23
so there it is. We nailed it !!!
Theoretically, if
pfsense
have the SSH key and SSH service, it can decrypt the payload and be able to perform filter the packet in this tunnel.
- Creating a SSH Tunnel. Enter password for
vma
:
ssh -D 9000 -C [email protected]
Explain all flags:
D
: Specifies a local "dynamic" application-level port forwarding. This option allows a user to tunnel network connections through an SSH server to bypass firewall restrictions. The port specified, 9000 in this case, is the local port that will listen for connections and forward them through the SSH connection.C
: Specifies compression of data before transmission.[email protected]
: The remote hostname and IP address to connect to.
So in this specific example, the command is setting up a SOCKS proxy on the local machine at port 9000
, which will forward all traffic to the remote machine at IP address 10.0.3.3
, through an encrypted SSH tunnel as user vma.
- On Firefox, go to "Setting" or access via URL "about:preferences". In "General" tab, go to "Network settings" --> Choose "Settings"
- Configure the proxy as below:
Then access facebook.com
again with the "Block-facebook-youtube" rule enabled. Now it works !!!
- Revert the proxy setting to "Use system proxy setting" in Firefox.
- Create new rule:
Try to create tunnel again:
The answer is "NO" !!!
On VM-A
, install SQuid Proxy
sudo apt-get install squid -y
sudo systemctl restart squid
On VM-B
, in Firefox --> "Network Settings"
By default, Squid Proxy will deny all traffic from accessing websites. Edit /etc/squid/squid.conf
--> Search for http_access deny all
--> Re-edit into http_access allow all
Note: Any changes applied in
/etc/squid/squid.conf
need to restart Squid service
On VM-B
, access to google.com
for testing. If everything is ok, this should be like this:
Explain:
We point our proxy directly to Squid proxy VM-A
. So the traffic will not flow through pfSense firewall. That's it !!
Context: There are some website contains malicious programs or not be included in your organization/school's policies. Try to redirect to another URL.
First, configuring Squid Proxy on VM-A
. Creating a script in /etc/squid/redirection-script.pl
, written by Perl:
#!/usr/bin/perl -w
use strict;
use warnings;
# Forces a flush after every write or print on the STDOUT
select STDOUT;
$| = 1;
# Get the input line by line from the standard input.
# Each line contains an URL and some other information.
while (<>) {
my @parts = split;
my $url = $parts[0];
if ( $url =~ /example\.com/ ) {
# URL Rewriting
print "http://www.uit.edu.vn\n";
}
else {
# No Rewriting.
print "\n";
}
}
Explain:
This script reads a file line by line using the while (<>)
construct. For each line, the script performs the following actions:
- It splits the line into an array of strings using the split function with the default delimiter (a whitespace character).
- It stores the first element of the resulting array in the variable $url.
- It performs a regular expression match on
$url
using the=~
operator to check if the string "example.com" appears anywhere in $url. - If the match is successful, the script prints "http://www.uit.edu.vn\n".
- If the match is not successful, the script prints a newline character.
This script can be used to perform URL rewriting on a file containing URLs. If a URL contains the string "example.com", the script replaces it with "http://www.uit.edu.vn". If the URL does not contain the string "example.com", the script leaves it unchanged.
Next, change permission for file execution:
sudo chmod 777 /etc/squid/redirection-script.pl
Finally, edit /etc/squid/squid.conf
and add two line below:
url_rewrite_program /etc/squid/redirection-script.pl
url_rewrite_children 5
On VM-B
, go to http://example.com. Then the webpage will automatically redirect to http://uit/edu.vn like this:
Note: Squid Proxy default can not process
HTTPS
websites. We need to rebuild the source with suitable flags
2. Re-edit Perl code above with condition: when accessing "http://example.com", an blocking-warn image floats in.
Change the redirecting path from "http://uit.edu.vn" to "https://i.imgur.com/q8axna8.png" (Image with Stop sign)
... # The same as above
print "https://i.imgur.com/q8axna8.png\n";
... # The same as above
Restart the service. When you access "http://example.com", the proxy will again redirect you to "http://uit.edu.vn". This 'cause the proxy Caching mechanism. To escape from Caching, you could:
- Clear cache
- Reconfigure caching
- Using private or incognito mode in browser
I opt for the third as it is more convenient :v Observe the result:
The error message "Unsupported Request Method and Protocol" suggests that the Squid proxy is unable to handle the request because it is not a standard HTTP request. The URL "https://i.imgur.com/q8axna8.png" appears to be an image, not a web page, and it may not be possible to directly access an image through a proxy server. We have to set up HTTPS
on the proxy.
<To be updated>
One of the main functions of a VPN is to create a secure connection that allows connections remote to the local network. VPN feature is also built-in on pfSense Firewall.
For added security, by default pfSense will enable the "Block private networks and loopback addresses". So we can't do operations like ping to WAN Interface okay.
Go to "Interfaces" --> "WAN". Uncheck the box:
Then you are welcomed to ping 10.0.3.4
1. What VPN connection protocols does pfSense Firewall support? What are the difference in their characteristics?
• Open VPN: highly configurable, secure, supports many encryption algorithms, good performance, be resistant to strong firewalls and open source.
• L2TP - IP SEC VPN (Layer 2 Tunnel Protocol): L2TP is an extension of the Point-to-Point Tunneling Protocol (PPTP) used by internet service providers (ISPs) to enable virtual private networks (VPNs). It does not encrypt the data passing through it, but relies on a set of protocols called IPsec
to encrypt data before sending, with higher performance and security effectiveness than PPTP, but using UDP port 500, so it is easily blocked by the NAT firewall.
2. Research and configure on pfSense, so that from VM-B
, we can open a VPN connection to pfSense server to access VM-A
.
For Server side:
- Creating Certificate Authority (CA) on PFSense: "System" --> "Certificate Manager" --> "CAs" --> "Add"
Then "Save"
- Creating Server Certificate for OpenVPN on PFSense: "System" --> "Certificate Manager" --> "Certificates" --> "Add/Sign"
Then "Save"
- Configure OpenVPN on PFSense: "VPN" --> "OpenVPN" --> "Wizard". Use default configuration, "Next" until "Step 9 of 11". We choose any "Tunnel Network" when traffic flows privately in OpenVPN Tunnel. Here, I choose
10.0.8.0/24
:
Then, in "Step 10 of 11", "Firewall Rule Configuration":
"Next" --> "Finished". That's all for server.
Now let's configure for client side:
- "VPN" --> "OpenVPN" --> "Client" --> "Add". Configure as below:
Your client IP:
Your username
and password
when connecting to VPN
Data encryption type, choose what you wish ^___^
- Install "OpenVPN Client Export" to export configuration file for client's use: "System" --> "Package Manager" --> "Available Packages"
"Install" --> "Confirm"
- Add VPN User: "System" --> "User Manager" --> "Add". Configure as below:
- Export VPN configuration with extension: "VPN" --> "OpenVPN" --> "Client Export"
Now you're good to go (●'◡'●). Transfer this file to VM-A
. On VM-A
.
Install openvpn service:
sudo apt install openvpn
sudo systemctl restart openvpn
Connect to VPN by:
sudo openvpn --auth-user-pass --config Desktop/pfSense-UDP4-1194-vpn-config.ovpn
Enter username
and password
on VPN server. DONE !!!
Go to "Diagnostics" --> "Backup & Restore" --> Click on "Download configuration as XML" to create a backup configuration for pfSense. Happy enjoy!