Sign In
Sign In

Introduction to OAuth 2

Introduction to OAuth 2
Hostman Team
Technical writer
Network
04.04.2025
Reading time: 6 min

The OAuth 2 is an authorization protocol designed to restrict access to personal accounts created on HTTP resources. Typical implementations include DigitalOcean, GitHub, and Facebook. OAuth 2 works by delegating the authentication process to the server where the account is located. This approach allows third-party applications to request access to user data, such as for registration using pre-filled credentials.

OAuth 2 can be used in cloud services, desktop computers, and mobile applications for smartphones and tablets. In this guide, we will explore how OAuth works and discuss the main practical applications of this tool.

OAuth Roles

OAuth 2 defines four main roles: the resource owner, the client, the resource server, and the authorization server. Let’s go through each role in detail.

Resource Owner

The resource owner is the user who is authenticated using their credentials to access their personal account. The accessible area may have restricted permissions—either read-only or with write and modification capabilities.

Server (Resource Server and Authorization Server)

  • The resource server stores user account data in a protected form.
  • The authorization server verifies the authenticity of entered login credentials and generates authorization tokens for applications. These tokens allow applications to access user data.

Both servers are logically combined into a unified system, which is perceived by external services through the API interface. Thus, we will refer to the resource and authorization servers collectively as the Service or API.

Client (Application)

The client refers to the application requesting access to the user’s account. Before activation, two conditions must be met: authentication within the application and a positive response from the API.

Protocol Overview

Having reviewed the OAuth 2 roles, let's look at the authorization protocol and the information exchange process. Below is a sequence of typical operations:

  1. The application prompts the user to enter authentication credentials.
  2. If the login and password are correct, an authorization grant is issued.
  3. The application sends a request to the API, including the authorization grant.
  4. If the application is authenticated, the server generates an access token for the specific instance, completing the authorization process.
  5. The application requests resources using the API.
  6. The resource server validates the token and provides data only upon confirmation.

The sequence may vary depending on the developer and the software’s purpose, but the general scheme remains consistent.

Registering an Application

Before using OAuth, an application must be registered with the service. This is typically done under the Developer or API section on the website. The following details are required:

  • Application name
  • Website where the application is hosted
  • Callback URL (Redirect URL)

The Callback URL is a link to the page that the service will open in case of access denial or after successful authorization.

Client Identification

Upon registering the application, user credentials are created—these include the Client ID and Client Secret:

  • Client ID is a public string used by the API to verify the application's legitimacy and generate URLs for authorized users.
  • Client Secret is used for authentication within the API and is only visible to the API and the application.

Authorization Grants

OAuth 2 provides four types of authorization grants depending on the situation:

  1. Authorization Code – Used for server-side applications.
  2. Implicit Grant – Suitable for mobile applications, including web versions.
  3. Resource Owner Password Credentials – Used for trusted applications, such as those integrated with an online service.
  4. Client Credentials – Used for API-based operations.

Now, let's examine each type in more detail.

Authorization Code Grant

This is the most common authorization method, as it is secure and suitable for applications where the source code and client secret are stored on a protected server.

Step 1: Create an Authorization Link

The application presents the user with the following link:

https://cloud.example.com/v1/oauth/authorize?response_type=code&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

Components:

  • authorize endpoint: Used for OAuth authentication via API.
  • client_id: Identifies the requesting application.
  • redirect_uri: Redirects the user after authorization.
  • response_type=code: Requests an authorization code.
  • scope=read: Specifies read-only access.

Step 2: User Authentication

When the user clicks the link, they are prompted to log in. Upon successful authentication, the application is either authorized or denied access.

Step 3: Authorization Code is Sent to the Application

If authorization is granted, the system redirects the browser to:

https://example.com/callback?code=AUTHORIZATION_CODE

Step 4: Request an Access Token

The application sends the authorization code to the server along with authentication details:

https://cloud.example.com/v1/oauth/token?client_id=CLIENT_ID&client_secret=CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=CALLBACK_URL

Step 5: Server Returns an Access Token

If authentication is successful, the API returns an access token:

{
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{
    "name":"User",
    "email":"info@example.com"
  }
}

The application is now connected to the server.

Implicit Grant

This method is used in mobile applications and web browsers. Unlike the Authorization Code Grant, it does not ensure the confidentiality of the client secret.

Step 1: Generate an Authorization Link

The authorization service provides a link:

https://cloud.example.com/v1/oauth/authorize?response_type=token&client_id=CLIENT_ID&redirect_uri=CALLBACK_URL&scope=read

Step 2: Authenticate the User

Upon successful authentication, the server returns an access token directly to the browser:

https://example.com/callback#token=ACCESS_TOKEN

Step 3: Extract and Use the Token

The application extracts the token from the URL and uses it for API requests.

Resource Owner Password Credentials Grant

This method involves the user entering credentials directly into the service. It is used when other methods are not viable, such as system-integrated applications.

https://oauth.example.com/token?grant_type=password&username=USERNAME&password=PASSWORD&client_id=CLIENT_ID

Upon successful authentication, the server returns an access token.

Client Credentials Grant

This method allows access to the service’s own resources:

https://oauth.example.com/token?grant_type=client_credentials&client_id=CLIENT_ID&client_secret=CLIENT_SECRET

If authentication is successful, an access token is returned.

Refreshing an Access Token

To refresh an access token before it expires:

https://cloud.example.com/v1/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN

Conclusion

We have explored the different ways to use OAuth in applications, depending on their requirements. Now, users understand how access to remote services is managed and what factors to consider when choosing an authorization method.

Network
04.04.2025
Reading time: 6 min

Similar

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
Linux

Port Forwarding in Linux with Iptables

Have you ever hosted a server (game or web) on your home computer and shared your IP address with friends, but no one could connect? The issue lies in your router, which hides connected devices behind its own IP address. Everything within the router is a local network, while everything outside is a global network. However, there is no direct mediator between them, only a barrier preventing external connections. The solution is port forwarding, a technology that directs external requests to an internal device and vice versa. In Linux operating systems, the iptables utility is used for this purpose, which will be the focus of this article. The commands shown in this guide were executed on a Hostman cloud server running Ubuntu 22.04. What Is Port Forwarding? Port forwarding (also known as port mapping) redirects network traffic from one port to another, either through a router (hardware-level) or a firewall (software-level). With port forwarding, devices within a local network become accessible from the global network. Without it, external requests cannot reach internal devices. Common scenarios where port forwarding is needed: Connecting to a home server (game server, surveillance cameras, data storage). Hosting game servers or websites on a home PC. Accessing a remote desktop. Remote device management. For example, if a server in a local network operates on port 8080, port forwarding allows it to be accessed from the global network through port 80. Example Setup: A computer with IP 192.168.1.100 (internal/gray IP) runs a web server listening on port 8080. The computer is within a Wi-Fi router’s local network, which has an external IP 203.0.113.10 (public/white IP), listening on port 80. All global network requests to port 80 on the router are forwarded to port 8080 on the internal computer. This setup allows us to redirect incoming traffic from the global network to the local network. How Does Port Forwarding Work in Linux? Linux has built-in tools for handling incoming and outgoing traffic. These tools act as a packet filtering and modification pipeline. Port forwarding in Linux is based on NAT (Network Address Translation), configured using the iptables system utility. What Is NAT? NAT (Network Address Translation) is a technique that converts external requests from the global network into internal requests within the local network (and vice versa). Technically, NAT modifies IP addresses and ports in data packets. It is not a standalone utility but a concept or approach. There are two main types of NAT: SNAT (Source NAT) – Modifies the source IP address in outgoing packets. DNAT (Destination NAT) – Modifies the destination IP address in incoming packets. While NAT protects the local network from external access, it requires port forwarding for incoming connections. What Is Iptables and How Does It Work? Iptables is a Linux utility used to configure NAT (and more) by modifying tables with rule chains that control traffic. Iptables has five main rule chains: INPUT – Handles incoming packets. FORWARD – Handles forwarded packets. OUTPUT – Handles outgoing packets. PREROUTING – Handles packets before routing. POSTROUTING – Handles packets after routing. Iptables has five tables, each using specific rule chains: filter – Allows or blocks packets (INPUT, FORWARD, OUTPUT). nat – Modifies IP addresses and ports (OUTPUT, PREROUTING, POSTROUTING). mangle – Alters packet headers (INPUT, FORWARD, OUTPUT, PREROUTING, POSTROUTING). raw – Controls connection filtering (OUTPUT, PREROUTING). security – Applies additional security policies (INPUT, FORWARD, OUTPUT). The rule chains act as hooks in the packet processing pipeline, allowing iptables to implement port forwarding in Linux. How Port Forwarding Works in Iptables Port forwarding in iptables follows a standard packet processing flow based on three possible directions: Incoming (INPUT) – Packets sent to the local system. Outgoing (OUTPUT) – Packets sent from the local system. Forwarded (FORWARD) – Packets routed through the system. Incoming Packets (INPUT) Processing Order raw (PREROUTING) – Connection filtering. mangle (PREROUTING) – Packet modification. nat (PREROUTING) – Changes the destination address. If the packet is for this system, continue to INPUT processing. Otherwise, forward it. mangle (INPUT) – Final packet modification. filter (INPUT) – Packet filtering. security (INPUT) – Security policy enforcement. Outgoing Packets (OUTPUT) Processing Order raw (OUTPUT) – Connection filtering. mangle (OUTPUT) – Packet modification. nat (OUTPUT) – Changes the destination address. filter (OUTPUT) – Final packet filtering. security (OUTPUT) – Security policy enforcement. mangle (POSTROUTING) – Final packet modification. nat (POSTROUTING) – Changes the source address. Forwarded Packets (FORWARD) Processing Order raw (PREROUTING) – Connection filtering. mangle (PREROUTING) – Packet modification. nat (PREROUTING) – Changes the destination address. Forwarding decision is made. mangle (FORWARD) – Packet modification. filter (FORWARD) – Packet filtering. security (FORWARD) – Security policy enforcement. mangle (POSTROUTING) – Final packet modification. nat (POSTROUTING) – Changes the source address. General Processing Order of Tables: raw mangle nat filter security Types of Port Forwarding Common types of port forwarding include: Local Forwarding – Redirects traffic within the same machine. Example: An application on a local server sends a request to a specific port. Interface Forwarding – Redirects traffic between different network interfaces. Example: A packet from the global network arrives on one interface and is forwarded to another. Remote Host Forwarding – Redirects traffic from a remote server to a local host. Example: A request from a remote server is forwarded to a local machine. Each type of port forwarding is implemented using a specific set of rules in the iptables tables. Using the Iptables Command In most Linux distributions, the iptables utility is already installed. You can check this by querying its version: iptables --version If iptables is not installed, you need to install it manually. First, update the package list: sudo apt update Then, install it: sudo apt install iptables -y By default, Linux uses the ufw firewall, which automatically configures iptables. To avoid conflicts, you must stop the ufw service first: sudo systemctl stop ufw Then, disable it: sudo systemctl disable ufw Iptables Command Structure The basic syntax of the iptables command is as follows: iptables [TABLE] [COMMAND] [CHAIN] [NUMBER] [CONDITION] [ACTION] In each specific command, only some of these parameters are used: TABLE: The name of one of the five tables where the rule is added. COMMAND: The operation to perform on a specific rule or chain. CHAIN: The name of the chain where the operation is performed. NUMBER: The rule number to manipulate. CONDITION: The condition under which the rule applies. ACTION: The transformation to be applied to the packet. Selecting a Table The -t flag specifies the table to operate within: For filter: iptables -t filter For nat: iptables -t nat For mangle: iptables -t mangle For raw: iptables -t raw For security: iptables -t security If the -t flag is not specified, the default table is filter. The security table is rarely used. Manipulating Rules We can perform different operations on rules within each chain: Add a rule to the end of a chain (-A): iptables -A INPUT -s 192.168.123.132 -j DROP This rule blocks incoming connections from the specified IP address. Delete a rule by its number (-D): iptables -D OUTPUT 7 Insert a rule at a specific position (-I): iptables -I INPUT 5 -s 192.168.123.132 -j DROP Replace a rule (-R): iptables -R INPUT 5 -s 192.168.123.132 -j ACCEPT This replaces a previously added blocking rule with an allow rule. Flush all rules in a chain (-F): iptables -F INPUT Manipulating Chains We can also perform operations on entire chains: Create a new chain (-N): iptables -N SOMENAME Delete a chain (-X): iptables -X SOMENAME Rename a chain (-E): iptables -E SOMENAME NEWNAME Set default policy for a chain (-P): iptables -P INPUT DROP This blocks all incoming connections to the server. Reset statistics for a chain (-Z): iptables -Z INPUT Setting Conditions Each rule can have conditions for its execution: Specify the protocol (-p): iptables -A INPUT -p tcp -j ACCEPT This allows incoming connections using the TCP protocol. Specify the source address (-s): iptables -A INPUT -s 192.168.123.132 -j DROP Specify the destination address (-d): iptables -A OUTPUT -d 192.168.123.132 -j DROP Specify network interface for incoming traffic (-i): iptables -A INPUT -i eth2 -j DROP Specify network interface for outgoing traffic (-o): iptables -A OUTPUT -o eth3 -j ACCEPT Specify the destination port (--dport): iptables -A INPUT -p tcp --dport 80 -j ACCEPT Specify the source port (--sport): iptables -A INPUT -p tcp --sport 1023 -j DROP Negate a condition (!): iptables -A INPUT ! -s 192.168.123.132 -j DROP This blocks all incoming connections except from the specified IP address. Specifying Actions Each table supports different actions: For the filter table: ACCEPT – Allow the packet. DROP – Block the packet. REJECT – Block the packet and send a response. LOG – Log packet information. RETURN – Stop processing in the current chain. For the nat table: DNAT – Change the packet’s destination address. SNAT – Change the packet’s source address. MASQUERADE – Change the source address dynamically. REDIRECT – Redirect traffic to the local machine. Port Forwarding with Iptables Local Port Forwarding To redirect local traffic from one port to another: sudo iptables -t nat -A PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 To remove the rule: sudo iptables -t nat -D PREROUTING -p tcp --dport 8080 -j REDIRECT --to-port 80 Forwarding Between Interfaces To forward port 8080 from interface eth0 to port 80 on eth1: sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 10.0.0.100:80 Then, allow packet forwarding: sudo iptables -A FORWARD -p tcp -d 10.0.0.100 --dport 80 -j ACCEPT Forwarding to a Remote Host To forward incoming packets to a remote server: Enable packet forwarding in the system settings: echo 1 > /proc/sys/net/ipv4/ip_forward Add a port forwarding rule: sudo iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 8080 -j DNAT --to-destination 192.168.1.100:80 Allow forwarded packets to be sent out: sudo iptables -t nat -A POSTROUTING -p tcp -d 192.168.1.100 --dport 80 -j MASQUERADE Alternatives to iptables for Port Forwarding It should be noted that iptables is not the only tool for traffic management. There are several popular alternatives. nftables nftables is a more modern tool for managing traffic in Linux. Unlike iptables, it does not have predefined tables, and its syntax is more straightforward and concise. Additionally, this utility uses a single command, nft, to manage all types of traffic: IPv4, IPv6, ARP, and Ethernet. In contrast, iptables requires additional commands such as ip6tables, arptables, and ebtables for these tasks. firewalld firewalld is a more complex traffic management tool in Linux, built around the concept of zones and services. This allows network resources to be assigned different levels of security. The configuration of firewalld is broader and more flexible. For example, instead of manually defining rules for each port, we can specify specific services. Additionally, firewalld provides a more interactive command-line interface, allowing real-time traffic management. Conclusion While there are alternatives, iptables remains the primary tool for traffic control in Linux. It provides a structured way to filter, modify, and forward packets, making it a powerful solution for managing network traffic.
09 April 2025 · 10 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