Sign In
Sign In

iptables: Overview and Practical Use

iptables: Overview and Practical Use
Hostman Team
Technical writer
Network
05.11.2024
Reading time: 11 min

The iptables utility allows you to manage the network firewall in Linux distributions. iptables is a popular command-line utility for interacting with the built-in Linux kernel firewall called Netfilter, which has been included in the Linux kernel since version 2.4. 

In this article, we will examine how iptables works and go through practical usage examples.

Installing iptables

As mentioned, iptables is included in nearly all Linux distributions, from the most common (Ubuntu, Debian, RHEL) to distributions like openSUSE, Arch Linux, Gentoo, and others. First, let's check if iptables is already installed on your cloud server by displaying its version with the command:

iptables --version

If this command returns a version number, iptables is already installed on the system. However, if you see the message iptables: command not found, you’ll need to install it manually. Below are instructions for installing iptables using package managers across various Linux distributions. Alternatively, you can compile and install iptables from the source code.

APT

For APT-based distributions (Ubuntu/Debian/Linux Mint/Kali Linux), use the command:

apt -y install iptables

RPM

For RPM-based distributions (CentOS, Fedora, Red Hat Enterprise Linux, ALT Linux), use one of the following commands:

For the YUM package manager:

yum -y install iptables

For the DNF package manager:

dnf -y install iptables

Pacman

For Pacman-based distributions (Arch Linux, ArchLabs, Manjaro), use the command:

pacman -S iptables

All commands must be run as the root user or as a regular user with sudo privileges.

How iptables Works

iptables operates using a system of rules. These rules control incoming and outgoing traffic, organized into chains that either allow or block traffic.

A more detailed breakdown of how iptables works is as follows:

  • Network packets pass through one or more chains.
  • As a network packet moves through a chain, each rule in that chain is applied to it. During this process, the packet is checked against specified criteria. If it does not meet a criterion, a specific action is applied to it. These actions can include allowing or blocking traffic, among other operations.

Key iptables Terminology

While working with iptables, you may encounter the following terms:

  • Chain: A sequence or set of rules that determine how traffic will be handled.
  • Rules: Defined actions that contain criteria and a target or goal.
  • Module: An added feature that provides extra options for iptables, allowing for more extensive and complex traffic filtering rules.
  • Table: An abstraction in iptables that stores chains of rules. iptables includes the following tables: Security, Raw, NAT, Filter, and Mangle. Each table has a specific function, described below.

iptables Tables

Filter Table

The Filter table is the default table, using three chains: OUTPUT, FORWARD, and INPUT.

  • INPUT: Controls incoming connections. For instance, this might manage incoming SSH connections.
  • FORWARD: Manages incoming connections not directed to the local device, typically used on a router.
  • OUTPUT: Controls outgoing connections, such as navigating to a website using a browser.

NAT Table

The NAT (Network Address Translation) table includes three chains: PREROUTING, POSTROUTING, and OUTPUT.

  • PREROUTING: Determines the destination IP address of a packet.
  • POSTROUTING: Alters the source IP address.
  • OUTPUT: Changes the target address of outgoing packets.

Mangle Table

The Mangle table is used to modify packet IP headers.

Raw Table

The Raw table provides a mechanism for marking packets to bypass connection tracking.

Security Table

The Security table enables interaction with various OS security mechanisms, such as SELinux.

iptables Rules

The rules in iptables are designed to control incoming and outgoing network traffic. Rules can also be used to configure port forwarding and create protocol-specific rules.

Each rule is made up of criteria and a target. The criteria of a rule are matched, and the specified actions are applied to the target object. If a packet doesn’t match a rule’s criteria, the next rule is processed. The decisions made by iptables are called actions. Below is a list of key actions for handling connections:

  • ACCEPT: Opens (allows) the connection.
  • DROP: Closes the connection without sending a response to the client.
  • QUEUE: Sends the packet to a queue for further processing by an external application.
  • RETURN: Returns the packet to the previous rule, stopping the processing of the current rule.
  • REJECT: Blocks the connection and sends an error message in response.
  • DENY: Drops the incoming connection without sending a response.
  • ESTABLISHED: Marks an already established connection, as the session has already received at least one packet

Practical Application of iptables

Let's look at using iptables in practice. All the commands below will work on any Linux distribution. iptables commands must be run as the root user or a regular user with sudo privileges.

To display the current iptables configuration (including all existing rules), use the command:

iptables --list

85c00f9e 64b3 4cea 9647 13304c7bb8c6

For a more detailed output, which includes the number and size of processed packets in the INPUT, FORWARD, and OUTPUT chains, along with IP addresses and port numbers in numeric format, use:

iptables --line-numbers -L -v -n

Ee0b2682 A15a 4737 Ad14 F4f1ebefd20e

You can also specify a specific chain to display rules for just that chain, such as:

iptables -L INPUT
iptables -L FORWARD
iptables -L OUTPUT

Initially, iptables does not create or store any rule chains, so the output of these commands may be empty.

Blocking IP Addresses

To block a specific IP address, add a rule to the INPUT chain and specify the appropriate table. In the command below, the table is explicitly set. If the -t option is omitted, the rule is added to the default Filter table. For example, to block the IP address 10.0.36.126:

iptables -t filter -A INPUT -s 10.0.36.126 -j REJECT

This command uses the following options:

  • -t: Specifies the table for the rule.
  • -A: Adds the rule to the specified chain, in this case, the INPUT chain.
  • -s: Specifies the source IP address to which the action applies.
  • -j: Specifies the action to take; here, traffic is rejected (action REJECT).

To block an entire subnet, specify it with the -s option:

iptables -A INPUT -s 10.0.36.0/24 -j REJECT

Or, you can specify the subnet mask in full format:

iptables -A INPUT -s 10.0.36.0/255.255.255.0 -j REJECT

To block outgoing traffic to a specific IP address, use the OUTPUT chain and the -d option:

iptables -A OUTPUT -d 10.0.36.126 -j REJECT

Blocking Ports

Ports can be blocked by specifying them directly. This is done with the --dport option, which designates the port of the service. Instead of a port number, you can use the service name. You must specify the protocol as well. For example, to block SSH connections from host 10.0.36.126 using the TCP protocol:

iptables -A INPUT -p tcp --dport ssh -s 10.0.36.126 -j REJECT

For the UDP protocol, use:

iptables -A INPUT -p udp --dport ssh -s 10.0.36.126 -j REJECT

Alternatively, to block SSH connections from 10.0.36.126 using the SSH service port (22), use:

iptables -A INPUT -p tcp --dport 22 -s 10.0.36.126 -j REJECT

To block SSH connections from any IP address over TCP:

iptables -A INPUT -p tcp --dport ssh -j DROP

Allowing an IP Address

To allow traffic from a specific IP address, use the ACCEPT action. In the example below, all traffic from the IP address 10.0.36.126 is allowed:

iptables -A INPUT -s 10.0.36.126 -j ACCEPT

To allow traffic from a specific range of IP addresses, for example, from 10.0.36.126 to 10.0.36.156, use the iprange module and the --src-range option:

iptables -A INPUT -m iprange --src-range 10.0.36.126-10.0.36.156 -j ACCEPT

Here:

  • iprange: A module for working with IP address ranges.
  • --src-range: Specifies the source IP address range.

To perform the reverse operation (allowing all traffic from the server to a specific IP range from 10.0.36.126 to 10.0.36.156), use the --dst-range option:

iptables -A OUTPUT -m iprange --dst-range 10.0.36.126-10.0.36.156 -j ACCEPT
  • --dst-range: Specifies the destination IP address range.

Opening Ports

To open a port, specify the protocol using the -p option. Supported protocols include tcp, udp, etc. A full list of supported protocols can be found in /etc/protocols:

cat /etc/protocols

Specify the port using the --dport option. You can use either numeric values or service names. The ACCEPT action is used to open ports.

To open port 22 for TCP traffic from IP address 10.0.36.126:

iptables -A INPUT -p tcp --dport 22 -s 10.0.36.126 -j ACCEPT

To open multiple ports at once, use the multiport module and the --dports option, listing the ports separated by commas. For example, to open ports 22, 80, and 443 over TCP from IP address 10.0.36.126:

iptables -A INPUT -p tcp -m multiport --dports 22,80,443 -s 10.0.36.126 -j ACCEPT
  • multiport: A module for managing multiple ports simultaneously.
  • --dports: Specifies multiple ports, unlike --dport, which supports only a single port.

Blocking ICMP Traffic

One commonly used feature in iptables is blocking ICMP traffic, often generated by the ping utility. To block incoming ICMP traffic, use the following command:

iptables -A INPUT -j DROP -p icmp --icmp-type echo-request

Image7

This command will prevent the ping command from receiving a response without displaying an error message. If you want to display an error message like "Destination Port Unreachable," replace the DROP action with REJECT:

iptables -A INPUT -j REJECT -p icmp --icmp-type echo-request

123

Allowing ICMP Traffic

To allow previously blocked ICMP traffic, run the following command:

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

However, it’s important to note that if ICMP traffic was previously blocked with this command:

iptables -A INPUT -j DROP -p icmp --icmp-type echo-request

and then allowed with:

iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT

the ICMP traffic will still be blocked, as the drop rule will be the first rule in the INPUT chain.

Blocking Traffic by MAC Address

In addition to IP addresses, traffic can be blocked based on the device’s MAC address. Below is an example to block traffic from a device with the MAC address 00:0c:29:ed:a9:60:

iptables -A INPUT -m mac --mac-source 00:0c:29:ed:a9:60 -j DROP
  • mac: A module for working with device MAC addresses.
  • mac-source: Specifies the MAC address of the device.

Allowing Traffic by MAC Address

To allow traffic from a specific MAC address, use this command:

iptables -A INPUT -m mac --mac-source 00:0c:29:ed:a9:60 -j ACCEPT

Blocking traffic by MAC address with iptables will only work if the devices are on the same network segment. For broader use cases, blocking traffic by IP address is generally more effective.

Allowing Traffic on the Loopback Interface

Traffic on the loopback interface can also be controlled. To allow incoming traffic on the loopback interface, use:

iptables -A INPUT -i lo -j ACCEPT

For outgoing traffic on the loopback interface, the command is:

iptables -A OUTPUT -o lo -j ACCEPT

Restricting Network Access by Schedule

One of the useful features of iptables is the ability to temporarily allow or restrict traffic to specific services or ports based on a schedule. For example, let’s say we want to allow incoming SSH access only on weekdays, Monday through Friday, from 9 AM to 6 PM. The command would look like this:

iptables -A INPUT -p tcp --dport 22 -m time --timestart 09:00 --timestop 18:00 --weekdays Mon,Tue,Wed,Thu,Fri -j ACCEPT
  • time: Module for working with time-based rules.
  • timestart: Specifies the start time for the rule.
  • timestop: Specifies the end time for the rule.
  • weekdays: Specifies the days of the week when the rule will be active, separated by commas. Supported values are: Mon, Tue, Wed, Thu, Fri, Sat, Sun, or numbers 1 to 7.

Saving iptables Rules

By default, user-created iptables rules are not saved automatically. This means that the rules are cleared after a server reboot or shutdown. To save the rules, install the iptables-persistent package with the following command:

apt -y install iptables-persistent

During the installation, two dialog boxes will appear, allowing you to save the current rules to /etc/iptables/rules.v4 for IPv4 and /etc/iptables/rules.v6 for IPv6.

To manually save all rules for the IPv4 protocol, use:

iptables-save > /etc/iptables/rules.v4

For IPv6 rules, use:

ip6tables-save > /etc/iptables/rules.v6

This method has a significant advantage: saved rules can be restored from the file, which is helpful, for example, when transferring rules to another host. To restore previously saved rules, run:

iptables-restore < /etc/iptables/rules.v4

If executing this command on a different host, transfer the rule file first and then execute the restore command.

Deleting Rules in iptables

You can delete rules in iptables using several methods.

Deleting a Specific Rule

One way to delete a rule is to target a specific rule in a chain using its line number. To display the rule numbers, use:

iptables -L --line-numbers

Image10

For example, in the INPUT chain, we might see two rules that open ports 80 and 443 over TCP for IP addresses 10.0.36.126 (rule number 1) and 10.0.36.127 (rule number 2). To delete rule number 2, use:

iptables -D INPUT 2

Then, display the list of all current rules to verify:

iptables -L --line-numbers

Rule number 2 should now be removed successfully.

Image1

Deleting All Rules in a Specific Chain

You can also delete all rules in a specific chain at once. For example, to clear all rules in the OUTPUT chain:

iptables -F OUTPUT

Deleting All Rules

To delete all rules across all chains, simply run:

iptables -F

Use caution with this command, as it will remove all existing rules, including potentially essential ones.

Conclusion

In summary, iptables is a powerful tool for managing the built-in firewall in Linux-based operating systems. Its extensive features and modular support allow flexible configuration for controlling network traffic.

For more detailed information on iptables, consult the official documentation or use the man iptables command in Linux-based systems.

Network
05.11.2024
Reading time: 11 min

Similar

Linux

How to Open a Port on Linux

Opening ports in Linux is an important task that allows certain services or applications to exchange data over the network. Ports act as communication gateways, allowing access to authorized services while blocking unauthorized connections. Managing ports is key to secure access, smooth app functionality, and reliable performance. Understanding Ports and Their Purpose Ports are the logical endpoints of network communication, where devices can send and receive information. HTTP uses port 80, HTTPS uses port 443, and SSH uses port 22. An open port means the service that listens for incoming network traffic is associated with it. A closed port, on the other hand, stops communication via that gateway. Maintaining availability and security requires proper management of Linux open ports. Check Existing Open Ports on Linux Before opening a port, check the open ports in Linux to see which ones are currently active. You may achieve this using several Linux commands. netstat To display open ports, run: netstat -tuln The netstat utility provides a real-time view of active network connections, displaying all listening endpoints. The -tuln flags refine the output to show only TCP and UDP ports without resolving hostnames. Note: In case netstat isn’t installed, install it via: sudo apt install net-tools ss The ss utility can also be utilized to check ports: ss -tuln Compared to netstat, the ss command is more recent and fast. It shows the ports that are in use as well as socket information. nmap For a detailed analysis of Linux open ports, use: nmap localhost The nmap utility scans the given host (localhost in this case) for open ports. This is useful for finding ports exposed to public networks. Note: You can install nmap on Linux via: sudo apt install nmap Opening Ports on Linux Firewall modification is required to grant access through a chosen endpoint. Linux provides several options for handling these tasks, including iptables, ufw, and firewalld. Here are the methods to open ports with these utilities. Method 1: Via iptables Iptables is a robust and lower level firewall utility that grants fine-grained control over network traffic. To open a port with iptables, take these steps: Add a Rule to Allow Traffic from a Specific Port  Enable HTTP access on port 8080 with this command: sudo iptables -A INPUT -p tcp --dport 8080 -j ACCEPT sudo: Execute the command as superuser. iptables: Refers to the firewall utility. -A INPUT: Inserts a rule in the input chain, controlling incoming traffic. -p tcp: Shows that the rule is for TCP traffic. --dport 8080: Points to port 8080 for the rule. ACCEPT: Specifies that incoming traffic matching the rule is accepted. This permits incoming TCP on port 8080. However, iptables changes are volatile and will be undone after reboot. Note: The iptables can be installed with persistent packages using: sudo apt install iptables iptables-persistent Save the Configuration For making the rule permanent and remain even after a system restart, store iptables rules via: sudo netfilter-persistent save This directive preserves current iptables or nftables rules such that they are preserved during reboots. Reload Changes Reload the firewall configuration as needed with: sudo netfilter-persistent reload Method 2: Via UFW Ufw (Uncomplicated Firewall) is a minimal front-end for managing iptables rules. It allows you to easily open ports with simple commands. This is how you can do it: Enable Ufw  First, ensure the ufw firewall is activated: sudo ufw enable Executing this command allows UFW to modify firewall settings. Note: UFW can be installed with: sudo apt install ufw Allow Traffic Via Specific Port  For instance, to open port 22 for SSH, use: sudo ufw allow 22/tcp sudo: Grants superuser privileges. ufw allow: Adds a rule to permit traffic. 22/tcp: Sets port 22 for communication while restricting the rule to TCP protocol. This permits access on port 22, enabling remote SSH connections. Verify the Firewall Status  To ensure the port is accessible and the rule is active, execute: sudo ufw status The status command displays all active rules, including the allowed ports. Method 3: Via Firewalld Firewalld is a dynamic firewall daemon present on Linux. It is simpler to customize the firewall rules compared to using iptables. Here’s how to enable port access via firewalld: Add a Permanent Rule for the Desired Port  To enable HTTPS access on port 443, run: sudo firewall-cmd --permanent --add-port=443/tcp firewall-cmd: Invokes the firewalld command. --permanent: Ensures the rule stays active after the firewall reloads or the system boots. --add-port=443/tcp: Opens port 443 to accept incoming TCP traffic. Note: Install firewalld on Linux via: sudo apt install firewalld Once installed, you should activate and run it: sudo systemctl enable firewalld sudo systemctl start firewalld Reload the Firewall  Finalize the settings to enable the newly defined policy: sudo firewall-cmd --reload Applying firewall modifications makes recent policy updates functional without rebooting. Verification Check whether the port is opened successfully: sudo firewall-cmd --list-all The --list-all command provides a complete list of rules, helping you determine if port 443 is open. Testing the Newly Opened Port Always check if the newly opened port is available for incoming connections. Here’s how: Using telnet Test the port opening via: telnet localhost port_number Successful access means the port is open and responsive. Using nmap Analyze the host to verify if the specified endpoint is accessible.: nmap -p port_number localhost The -p flag specifies the port to scan. Using curl Check HTTP service availability: curl localhost:port_number A successful response confirms the service is running on the opened port. Troubleshooting Common Issues Ports opening may occasionally fail due to configuration errors or conflicting software settings. Follow these tips: Verify Firewall Rules: Run iptables -L or ufw status to assess firewall restrictions and permissions. Check Service Status: Check if the assigned service is active with systemctl status <service-name>. Opening Specific Ports Based on Protocol Understanding the protocol used by the service can help configure ports more effectively. For instance, web traffic typically uses TCP (Transmission Control Protocol) for stable communication, while certain gaming services may require UDP (User Datagram Protocol) for faster packet transmission. Opening a TCP Port To access port 3306 for MySQL traffic: sudo ufw allow 3306/tcp This explicitly permits TCP traffic through port 3306, ensuring stable communication for database queries. Opening a UDP Port To access port 161 for SNMP (Simple Network Management Protocol), run: sudo ufw allow 161/udp UDP provides faster, connectionless communication, ideal for monitoring tools like SNMP. Managing Port Accessibility Once a port is opened, controlling its visibility ensures security and prevents unauthorized access. Restricting Access to Specific IPs To limit port access to a specific IP address (e.g., 192.168.1.100): sudo ufw allow from 192.168.1.100 to any port 22 This allows SSH access via port 22 only from the specified IP address, enhancing security. Closing Ports To revoke access to port 80: sudo ufw deny 80/tcp This denies incoming traffic on port 80, effectively closing it for HTTP services. Conclusion Confirming open ports in Linux is a key step for optimizing network functionality and deploying services effectively. With the use of utilities such as iptables, ufw, or firewalld, you can control traffic securely for your apps. You need to test and debug in order to confirm the port is open and working as expected. From web servers to SSH access, to other network services, port management skills ensure smooth operations and better security.
01 July 2025 · 7 min to read
DNS

DNS Configuration for IPv6: Step-by-Step Tutorial

The internet is gradually transitioning to IPv6, and an increasing number of websites, applications, and devices are adopting it. But having an IPv6 address alone isn’t enough. To make everything work properly, you need to configure DNS correctly—both on the server side and on your own computer. Without DNS, no connection will work: the browser simply won’t know where to send the request. This is especially critical for IPv6. If you forget to set the necessary DNS records, your site will become invisible to many users, and even content that used to open just fine may stop working on client devices. How to Check if Your ISP Supports IPv6 This guide is relevant only if your internet provider supports IPv6. Linux-based OS Run the following command: ip -6 addr show If you see interface addresses starting with 2xxx: or 3xxx:, then your provider supports IPv6. macOS Use the command: ifconfig If your ISP assigns an IPv6 address, it will look something like this: Windows Open Command Prompt by pressing Win + R, then type cmd. Enter the following command: ipconfig You should see output like this: What Is DNS for IPv6, and Why Is It Important? DNS is like the internet’s address book. When a user types a website address, the browser doesn’t know where to go—it needs an IP address. DNS translates human-readable addresses into a numeric IP address that devices and networks can use. You need to configure DNS for IPv6 in two places: 1. On the Server (where your website or service is hosted) This enables browsers to find your site via IPv6. If your domain’s DNS zone doesn’t contain an AAAA record with the server’s IPv6 address, browsers won’t even know that they can use the new protocol to access your site. As a result, the site may load slowly or not at all for users with IPv6-only access. 2. On the Client Side (your computer or router) Your computer also needs to know which DNS server to use in order to resolve site addresses into IPv6 format. If your computer or router doesn’t have access to a DNS server that supports IPv6, it won’t open the site, even if your ISP supports IPv6. You need to set up DNS for IPv6 so that the internet continues working quickly, reliably, and without interruptions under the new protocol. Without proper configuration, IPv6 might be available—but not functional. The Best Public IPv6 DNS Servers To ensure stable and fast performance, your device must know which DNS server to query. Usually, the router handles this: it receives the settings from your ISP and distributes them to the network. But if your ISP doesn’t support IPv6 or their DNS is unstable, you can manually specify public DNS servers that support IPv6. These are free, reliable addresses accessible from anywhere in the world: Name Primary IPv6 DNS Address Secondary IPv6 DNS Address Google DNS 2001:4860:4860::8888 2001:4860:4860::8844 Cloudflare 2606:4700:4700::1111 2606:4700:4700::1001 Quad9 2620:fe::fe 2620:fe::9 OpenDNS 2620:119:35::35 2620:119:53::53 All of these services: support IPv6 without additional setup, respond quickly to queries worldwide, protect against fake and malicious sites (especially Quad9 and OpenDNS). When Should You Set DNS Manually? Follow the instructions below if any of the following apply: Your device does not automatically receive DNS server settings. Your ISP does not support IPv6 at the DNS level. Websites load slowly or return “address not found” errors. The next sections explain how to manually configure DNS servers. It only takes a few minutes and results in a stable, error-free internet connection. Configuring DNS IPv6 on Windows If you have internet access but websites won’t load, Windows might not know which DNS server to use for IPv6. You can fix this easily by setting the correct addresses manually. This method works for both Windows 10 and 11—the interface is nearly identical. Open Network Connections: Press Win + R, type ncpa.cpl, and hit Enter. A window with all connections (Ethernet, Wi-Fi, etc.) will open. Find your active connection. It’s usually called “Local Area Connection” or “Wireless Network”.  Right-click on it → select Properties. Choose Internet Protocol Version 6 (TCP/IPv6). In the list of components, find this line and click the Properties button. Enter the DNS servers manually: Check Use the following DNS server addresses. Type in: Preferred: 2001:4860:4860::8888 Alternate: 2001:4860:4860::8844 Save your settings. Click OK → OK, then close the window. Windows will now use the specified DNS servers for IPv6 connections. Configuring IPv6 DNS in Linux DNS configuration in Linux depends on the edition you're using (desktop or server) and the network management tool used (NetworkManager, systemd-networkd, or manual configuration). To ensure everything works correctly with IPv6, you need to determine who is responsible for the network and DNS in your system and then choose the appropriate configuration method. How to Find Out What Your Distribution Uses Open a terminal and run: nmcli device If the command returns a list of interfaces and their statuses, you’re using NetworkManager. If nmcli is not installed, try: networkctl If you see interfaces with the status routable, configured,  you're using systemd-networkd. Ubuntu Desktop, Fedora, Manjaro — Using NetworkManager If you use a graphical environment (GNOME, KDE, Xfce) and see a network icon in the panel — most likely you're using NetworkManager. Via GUI: Go to Settings → Network → Select active connection → IPv6 In the DNS section: Switch the mode to “Manual” or “Advanced” Enter DNS addresses, e.g.: 2001:4860:4860::8888 and 2001:4860:4860::8844 Save and restart the connection Via terminal: nmcli connection modify eth0 ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844" nmcli connection modify eth0 ipv6.ignore-auto-dns yes nmcli connection up eth0 Replace eth0 with your actual interface name (check it by running nmcli device). Ubuntu Server (18.04+, 20.04+, 22.04+) — Using Netplan On Ubuntu server editions, netplan is used to generate configuration for systemd-networkd. Open the configuration file, for example: sudo nano /etc/netplan/01-netcfg.yaml Add IPv6 addresses in the nameservers section. Be sure to strictly follow YAML formatting — use spaces only, no tabs. Usually, indentations are multiples of 4 spaces. In the addresses field, insert the IPv6 address with /64. In the gateway6 field, insert the gateway — drop the last group of your IPv6 address and replace it with 1 to get the gateway address.  network: version: 2 ethernets: eth0: dhcp4: true dhcp4-overrides: use-dns: false dhcp6: false addresses: - 2001:0db8:a::0370/64 gateway6: 2001:0db8:a::1       match: macaddress: <insert your machine’s MAC address> nameservers: addresses: - 2001:4860:4860::8888 - 2001:4860:4860::8844 Apply the changes: sudo netplan apply After applying the changes, verify that the correct DNS servers are in use. If the DNS Servers field displays incorrect servers, they are likely being automatically delivered via DHCP. Disable this as follows: Ensure correct permissions on the YAML file: sudo chmod 600 /etc/netplan/01-netcfg.yaml Delete the old resolv.conf and create a symlink: sudo rm -f /etc/resolv.conf sudo ln -s /run/systemd/resolve/resolv.conf /etc/resolv.conf If you get the error “Unable to resolve host”, add the hostname to /etc/hosts: HOSTNAME=$(hostname) sudo sed -i "/127.0.1.1/d" /etc/hosts echo "127.0.1.1 $HOSTNAME" | sudo tee -a /etc/hosts Enable systemd-resolved (if it’s not already): sudo systemctl enable systemd-resolved --now Apply configuration and restart services: sudo netplan apply sudo systemctl restart systemd-networkd sudo systemctl restart systemd-resolved Recheck the result: resolvectl status resolvectl dns At this point, DHCP-based DNS should be fully disabled. Modern Systems with systemd-resolved If your system uses systemd-resolved directly (e.g., Arch Linux, or Ubuntu with systemd), you can define DNS via the config file. Open the configuration file: sudo nano /etc/systemd/resolved.conf Add the following lines: [Resolve] DNS=2001:4860:4860::8888 2001:4860:4860::8844 FallbackDNS=2606:4700:4700::1111 Restart the service: sudo systemctl restart systemd-resolved Manual Configuration via resolv.conf — If Nothing Else Works Sometimes, it's easiest to make changes directly in /etc/resolv.conf, especially in minimal systems or containers. Open the file: sudo nano /etc/resolv.conf Add the lines: nameserver 2001:4860:4860::8888 nameserver 2001:4860:4860::8844 Keep in mind that the system often overwrites this file. To preserve settings: sudo chattr +i /etc/resolv.conf Configuring IPv6 DNS on a Router If you've already configured IPv6 DNS on your server and PC, but the site still won't open via the new protocol, check your router settings. The router distributes the internet and tells devices where to send DNS queries. If no IPv6-enabled DNS servers are set on the router, your home devices may still use the old protocol — even if the ISP has switched to IPv6. Where to Find IPv6 DNS Settings It depends on the model, but the typical path is: Router settings → Internet / WAN → IPv6 → DNS. If there is a separate DNS tab, go to it. Some models hide these parameters in Advanced sections. Example: TP-Link Router Go to the router’s interface: 192.168.0.1 or tplinkwifi.net Enter your login and password Go to Advanced → IPv6 Enable IPv6 — it’s usually off by default In WAN connection settings, check Configure the DNS server manually Enter your selected IPv6 DNS addresses, e.g.: 2001:4860:4860::8888 2001:4860:4860::8844 Save changes and reboot the router Example: Keenetic Router Go to my.keenetic.net From the menu, select Internet → Connection Go to the DNS Servers tab Check Manual Enter IPv6 addresses (e.g., Google DNS) Apply changes and reboot the router What to Do If DNS Doesn’t Accept IPv6 Check whether your router supports IPv6 (not all older models do). Make sure your ISP has assigned a global IPv6 address (and not just fe80::). Try updating your router’s firmware — this often resolves the issue. How to Test DNS over IPv6 Testing DNS over IPv6 is easy — both in a browser and via the terminal. It takes just a few minutes and quickly helps identify where the problem is: in the DNS, the network, or IPv6 itself. In the Browser The simplest method is to open a testing site: test-ipv6.com The page will show: Whether there is an IPv6 connection. Which protocol is used by default (IPv4 or IPv6). Whether DNS over IPv6 is working. Whether popular websites have AAAA records. If everything is green, it’s working fine. If there’s an error, the site will tell you what the issue is. In the Terminal (Linux, macOS) Check the AAAA DNS record: dig AAAA google.com If the response includes an IPv6 address (e.g., 2a00:1450:4009::200e), then DNS over IPv6 is working. Check which DNS servers are being used: resolvectl status This shows active interfaces and DNS servers (including IPv6 ones). Check whether traffic goes through IPv6: ping6 google.com Or: curl -6 https://ifconfig.co If the command executes and shows an IPv6 address, then IPv6 connectivity is active. Solving Common Issues Below is a cheat sheet for resolving problems frequently encountered when configuring IPv6 DNS: Symptom Problem Solution Websites open, but slowly. ping6 works, but ping is faster. The browser tries IPv6 first, then falls back to IPv4. The DNS server responds too slowly. Often, the ISP's default DNS is the culprit. Switch to a fast public DNS server. See "Configuring IPv6 DNS in Windows" or "Configuring IPv6 DNS in Linux". ping6 google.com → “Name or service not known” The DNS client is not receiving IPv6 responses: either the server addresses are incorrect or IPv6 is disabled on the interface. Check if IPv6 is active using ip -6 addr. Make sure resolvectl status shows an IPv6 DNS server. If not, set one manually (see Windows or Linux setup guides). Internet stops working after netplan apply. There’s a syntax error in the YAML file or the gateway is missing. Check the file using netplan try. If there’s an error, roll back and reapply the changes carefully. Watch for typos and fix indentation — use two spaces per level. No active connections in Ubuntu GUI. Netplan uses systemd-networkd, while the GUI expects NetworkManager. Either edit Netplan for a server setup, or install NetworkManager and change renderer: NetworkManager in the config file. nslookup -type=AAAA site.com in Windows shows “Non-existent domain”. The router does not have IPv6 DNS set, or its firmware does not support the protocol. Log in to the router's admin panel → “IPv6” → “DNS” → enter Cloudflare or Google DNS. Update firmware if the “IPv6” section is completely missing. Docker container ignores IPv6 DNS. Docker daemon uses its own resolv.conf copied at startup. Add the DNS address to /etc/docker/daemon.json, or pass it when launching the container: docker run --dns 2606:4700:4700::1111 alpine systemd-resolved continuously caches a SERVFAIL error. An upstream DNS server failed; the failed response is cached. Clear the cache and change DNS: sudo resolvectl flush-caches sudo systemd-resolve --set-dns=2001:4860:4860::8888 --interface=eth0 A site with HSTS loads via HTTPS only over IPv4. The certificate has only an A record; there's no AAAA record — the browser doesn’t trust it. Issue a certificate that validates both IP versions. For Let’s Encrypt:   sudo certbot --preferred-challenges http -d site.com -d '*.site.com' ping6 to a local host is OK, but gives “Network unreachable” to the internet. The ISP assigned a prefix but no gateway (gateway6 is not set). Manually add a gateway: gateway6: 2a03:6f01:1:2::1 Apply the changes: sudo netplan apply IPv6 address is present, but DNS queries go to 192.168.0.1.  The router distributes IPv4 DNS via DHCPv6 Option 23; the system gives them higher priority. Manually set IPv6 DNS with the highest priority: sudo resolvectl dns-priority eth0 0 dig @2606:4700:4700::1111 google.com works, but dig google.com doesn't. systemd-resolved listens on 127.0.0.53, but a local firewall blocks outbound DNS packets. Allow outbound traffic on port 53 (UDP and TCP) or disable UFW: sudo ufw allow out 53 Compare your symptom with the first column and check the brief diagnosis in the second column. Execute the command(s) in the third column and verify the result. If the issue isn’t resolved, return to the DNS setup steps. Conclusion The transition to IPv6 is slow, but inevitable. More and more ISPs are issuing only IPv6 addresses, more hosting providers are operating with Dual Stack, and more services are checking for IPv6 support by default. And if DNS is misconfigured, connections fail, websites won’t load, and users will leave for services that work. The good news? It all takes 5–10 minutes: Add an AAAA record in your hosting panel; Set reliable public DNS servers on your server, router, and client devices; Check the result — and forget about the issue. IPv6 is not about the future — it’s about ensuring your website, service, or home network works reliably right now. And a properly configured DNS is your ticket into this new Internet.
17 June 2025 · 13 min to read
SSH

How to Create an SSH Tunnel for Secure Connections over VNC

One of the major drawbacks of the VNC (Virtual Network Computing) protocol for remote access to computers is the complete lack of session encryption.  Image source: FAQ on the TightVNC website One way to address this issue is by creating an SSH tunnel over which the VNC session will run, ensuring full encryption of the VNC session. An SSH tunnel creates an encrypted data channel between the client device and the server. In addition to establishing a secure connection to the remote device, an SSH tunnel can also be used to transfer data. In this article, we will explore several methods for creating an SSH tunnel, including using the standard ssh utility, as well as third-party client applications such as PuTTY and MobaXterm. Prerequisites A server or virtual machine with VNC installed. You can use TightVNC for this. We explain how to install it in another article. A second server or virtual machine with a pre-installed Linux OS with a graphical interface. You can use any modern Linux distribution or a home computer or laptop running Windows. Both Home and Professional editions, as well as Windows Server versions, are suitable. Creating an SSH Tunnel  Method 1. The ssh Utility Let’s start by setting up an SSH tunnel using the standard OpenSSH client, which comes pre-installed by default on almost all modern Linux distributions, as well as on Windows operating systems starting from Windows 10 version 1709 and above. Windows Server 2019 and Windows Server 2022 would also work.  On Windows systems, you can also use any WSL distribution (Windows Subsystem for Linux). The following command for setting up an SSH tunnel works the same on both Linux and Windows: ssh -L 5901:localhost:5901 root@<server-IP-address> Where: -L — the flag for local port forwarding. In local forwarding, a port from the client device is forwarded to the server. All subsequent connections to this local port will pass through the SSH tunnel. 5901:localhost:5901 — syntax for forwarding the remote port. In this example, we inform SSH that we want to forward port 5901 (the port of the VNC server) located on the remote server to gain access to the VNC server. At the same time, we also open port 5901 on our local device (localhost). root@<server-IP-address> — the standard syntax for SSH connection. After entering the command, the system will prompt for the user’s password, and upon successful entry, you will log into the server. After this, the SSH tunnel will be established. It's important to remain connected to the server; otherwise, the SSH session (and the tunnel) will be interrupted. If you need to launch the SSH tunnel in "daemon" mode (in the background), use the -fNT options, for example: ssh -fNT -L 5901:localhost:5901 root@<server-IP-address> Where: -f — after the password is entered, instead of launching a shell, the ssh process will switch to the background; -N — do not execute any command on the remote server after starting the tunnel; -T — disables the use of a terminal. Once the SSH tunnel is successfully established, you can connect using any VNC client utility, for example, TightVNC Connection. Launch the utility and enter the address localhost::5901 in the “Remote Host” field: Note: The use of two colons after localhost applies only to the TightVNC Connection program. After entering the address, click the “Connect” button. The program will request the password for the VNC session, which is set during the VNC server configuration: After entering the password, a window with the graphical interface of the server will open: All traffic between your device and the VNC server is now fully protected and encrypted. Method 2. PuTTY In addition to using the standard ssh utility, a tunnel can also be set up using the popular client utility for connecting to remote servers — PuTTY. To do this, follow these steps: Launch PuTTY and in the main menu fill in the following fields: Host Name (or IP address): enter the IP address of the VNC server; Port: specify the port used by SSH; Saved Sessions: enter any name for the session so that it can be saved and launched quickly in the future. Click the “Save” button to save the current session. In the left menu, find the “Connection” section, expand it, and go to “Tunnels”: In the opened section, fill in the following details: Source port: specify the port to be opened on the client device, e.g., 5901; Destination: enter the IP address of the VNC server and the VNC server’s port. After entering the data, click the “Add” button: Return to the PuTTY main menu (the “Session” section) and connect to the server by clicking the “Open” button. During the first login, you will need to accept the host key by clicking the “Accept” button. After entering the user account password, the server terminal will open: Without closing the PuTTY session window, open your VNC client application (e.g., TightVNC Connection) and enter the address localhost:5901: After entering the VNC session password, the server’s graphical interface will be displayed. Method 3. MobaXterm Another popular program for Windows OS used to connect to remote servers is MobaXterm. It can also be used to create an SSH tunnel. To do so, follow these steps: Launch the program and click on the “Tunneling” tab at the top: In the tunnel settings window, make sure the option “Local port forwarding” is selected and fill in the following information: In the “My computer with MobaXterm” section, enter the local port (5901) to be opened on the device; In the “SSH server” section, enter the address of the remote VNC server, along with the login and password to connect to the server; In the “Remote server” section, enter localhost as the address and 5901 as the port. Click the “Save” button to save the settings. In the opened window, click the start button in the “Start/stop” section: Once the SSH tunnel is launched, go to the “Session” section: In the “Remote hostname or IP address” field, enter localhost, and in the “Port” field, enter 5901: Click the “OK” button to connect. After entering the VNC session password, the server’s graphical interface will appear: Conclusion Although the VNC protocol does not encrypt its traffic by default, this issue can be resolved by using an SSH tunnel. In this article, we reviewed several methods for setting up an SSH tunnel on your device.
16 June 2025 · 6 min to read

Do you have questions,
comments, or concerns?

Our professionals are available to assist you at any moment,
whether you need help or are just unsure of where to start.
Email us
Hostman's Support