# IPtables + forwarding https traffic

## mahdi1234

Hi there,

I have a server running apache with multiple ssl enabled hosts, each of those hosts run on their own local IP and local eth card. And I have one external public IP. What I need to do is to forward https traffic from public IP to relevant internal IP, what is the best solution?

```

127.0.0.1    localhost

10.1.1.1    domain.com

10.1.1.2    domain2.com
```

```
eth0      Link encap:Ethernet  HWaddr 52:54:00:00:0d:1f  

          inet addr:XX.XX.XX.XX  Bcast:XX.XX.XX.XXX  Mask:255.255.255.0

          inet6 addr: XXXX::5054:ff:XXXX:d1f/64 Scope:Link

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          RX packets:557476 errors:0 dropped:4974 overruns:0 frame:0

          TX packets:38937 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:1000 

          RX bytes:69733697 (66.5 MiB)  TX bytes:40023011 (38.1 MiB)

          Interrupt:10 Base address:0x8000 

eth0:1    Link encap:Ethernet  HWaddr 52:54:00:00:0d:1f  

          inet addr:10.1.1.1  Bcast:10.1.1.255  Mask:255.255.255.0

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          Interrupt:10 Base address:0x8000 

eth0:2    Link encap:Ethernet  HWaddr 52:54:00:00:0d:1f  

          inet addr:10.1.1.2  Bcast:10.1.1.255  Mask:255.255.255.0

          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1

          Interrupt:10 Base address:0x8000 

lo        Link encap:Local Loopback  

          inet addr:127.0.0.1  Mask:255.0.0.0

          inet6 addr: ::1/128 Scope:Host

          UP LOOPBACK RUNNING  MTU:16436  Metric:1

          RX packets:3799 errors:0 dropped:0 overruns:0 frame:0

          TX packets:3799 errors:0 dropped:0 overruns:0 carrier:0

          collisions:0 txqueuelen:0 

          RX bytes:498615 (486.9 KiB)  TX bytes:498615 (486.9 KiB)

```

Now basically what I need is when user accesses https://domain.com or https://domain2.com to properly redirect - what do I need to set in iptables or is there some other solution? My current iptables rules are as following, nothing in NAT table currently 

```

Chain INPUT (policy ACCEPT)

target     prot opt source               destination         

fail2ban-ssh-ddos  tcp  --  anywhere             anywhere            multiport dports ssh

fail2ban-ssh  tcp  --  anywhere             anywhere            multiport dports ssh

ACCEPT     all  --  anywhere             anywhere            

REJECT     all  --  anywhere             loopback/8          reject-with icmp-port-unreachable

ACCEPT     all  --  anywhere             anywhere            state RELATED,ESTABLISHED

ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:www

ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:https

ACCEPT     tcp  --  anywhere             anywhere            tcp dpt:322

ACCEPT     icmp --  anywhere             anywhere            icmp echo-request

LOG        all  --  anywhere             anywhere            limit: avg 5/min burst 5 LOG level debug prefix `iptables denied: '

REJECT     all  --  anywhere             anywhere            reject-with icmp-port-unreachable

Chain FORWARD (policy ACCEPT)

target     prot opt source               destination         

REJECT     all  --  anywhere             anywhere            reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)

target     prot opt source               destination         

ACCEPT     all  --  anywhere             anywhere            

Chain fail2ban-ssh (1 references)

target     prot opt source               destination         

RETURN     all  --  anywhere             anywhere            

Chain fail2ban-ssh-ddos (1 references)

target     prot opt source               destination         

RETURN     all  --  anywhere             anywhere         
```

thanks & cheers

----------

## Hu

There is no need to use interface aliases for this.  You can directly assign several IP addresses to a single physical interface.

You have two options for the public part of it.  The first option is to get one public IP address per name.  The second option is to declare that SNI support is mandatory[1] for your clients.  If you go with the first route, then run iptables -t nat -A PREROUTING -i wan-interface -d IP-of-domain.com -p tcp --dport 443 -j DNAT --to-destination internal-IP-of-domain.com.  Repeat with appropriate substitutions for domain2.com.  If you go with the SNI route, then just redirect all externally generated port 443 traffic to a single internal IP address and let Apache sort it out.

[1] You can serve up to one domain to clients without SNI support, by making that the default domain.

----------

## mahdi1234

Thanks, the thing is I have only one public IP and with the rule you have mentioned it works perfectly for just one domain. Though is there any way how to make access to more https domains/subdomains with one public ip and multiple internal IP's?

With SNI it never worked for me well (using both wildcard and name based virtuals it never connected via ssl properly, only way which worked for me was to have IP based virtuals :/).

----------

## Hu

When using name-based virtual hosting, with or without SNI, you do not need multiple internal IP addresses.  You only need separate internal addresses if you want to use IP-based virtual hosting.  In turn, you can only use IP-based virtual hosting if you have multiple public IP addresses, and map each public IP to an internal IP.

You can serve unlimited http domains with name-based virtual hosting.  You can serve unlimited https domains with name-based virtual hosting and SNI.  If you cannot use SNI, then you must have one external IP:port for each unique certificate you plan to serve.  You may be able to play games with name-based virtual hosting, SSL, and no SNI, if all the sites you serve share a single certificate.

----------

## mahdi1234

Thanks for all the info, yes, port mapping works fine for me though I would definitely prefer clean method.

Here's my config when not using port mapping - it works fine for first domain, however second address always shows content of first defined host, would you have any idea what's wrong? SNI shall be enabled, browser should support SNI as well.

```
NameVirtualHost *:80

Listen 80

<IfModule mod_ssl.c>

   NameVirtualHost *:443

   Listen 443 https

</IfModule>

<IfModule mod_gnutls.c>

    Listen 443

</IfModule>

```

```
<VirtualHost subdomain1.domain.com:443>

    ServerAdmin webmaster@localhost

    ServerName subdomain1.domain.com

    DocumentRoot /var/www/subdomain1.net/www/

    <Directory />

   Options FollowSymLinks

   AllowOverride None

    </Directory>

    <Directory /var/www//www/fotoluzt.net/www>

   Options Indexes FollowSymLinks MultiViews

   AllowOverride all

   Order allow,deny

   allow from all

    </Directory>

    SSLEngine on

    SSLCertificateFile /etc/apache2/ssl/domain.com.crt

    SSLCertificateKeyFile /etc/apache2/ssl/domain.com.key

    SSLStrictSNIVHostCheck On

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,

    # alert, emerg.

    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

<VirtualHost subdomain2.domain.com:443>

    ServerAdmin webmaster@localhost

    ServerName subdomain2.domain.com

    DocumentRoot /var/www/domain.com/subdomain2/

    <Directory />

   Options FollowSymLinks

   AllowOverride None

    </Directory>

    <Directory /var/www/domain.com/subdomain2/>

   Options Indexes FollowSymLinks MultiViews

   AllowOverride all

   Order allow,deny

   allow from all

    </Directory>

    SSLEngine on

    SSLCertificateFile /etc/apache2/ssl/subdomain2.domain.com.crt

    SSLCertificateKeyFile /etc/apache2/ssl/subdomain2.domain.com.key

    SSLStrictSNIVHostCheck On

    ErrorLog ${APACHE_LOG_DIR}/error.log

    # Possible values include: debug, info, notice, warn, error, crit,

    # alert, emerg.

    LogLevel warn

    CustomLog ${APACHE_LOG_DIR}/access.log combined

</VirtualHost>

```

PS - using <VirtualHost *:443> doesn't work at all

----------

## Hu

Sorry, no idea.  I do not use SNI.

----------

