SmartOS Virtualization with one public IP address

Yes, you can!

For general help with SmartOS:

Google treats SmartOS as a synonym for Solaris. Always use the search located at smartos.org; do not use Google directly. #SmartOS on Freenode and the mailing list are also invaluable resources.

Security concerns with a single IP setup at a datacenter:

In SmartOS you typically have an admin interface (private/LAN) and a public one (public/WAN). I realize this may not be possible in your deployment, but it's very important that to know that KVM virtual hosts will run unprotected VNC on the admin interface. You will need to secure that using a firewall or configuration change.

What you'll want to do is set up a zone that will act as a firewall,gateway,load balancer, etc. That firewall zone will have two nics, one on the admin interface, one on the WAN. You can place all of your guests on a virtual switch which will be like having them connected to a physical one.

Since you only have one IP, which I would try to rectify, this can be tricky to set up in a zone, if you mess up your network configuration you may loose access to the machine. Although generally not advised, you may need to run your firewall in the global zone.

  1. For the guests to get out to the internet, set up NAT: http://wiki.smartos.org/display/DOC/NAT+using+Etherstubs

  2. For incoming https/http: I run an nginx instance and use a file for each service/website in the sites-available/sites-enabled folders. The default configuration of NGINX with SmartOS is minimalistic and will not contain these folders.

  3. For incoming tcp/udp services: You can use the built-in firewall (see man fwadm) in your firewall zone or use HAProxy if you want to do virtual hosts. (You could use HAProxy exclusively and eliminate NGINX)


I've setup a reproducible gist for this here. It's setup at github using permalinks, and I keep it up to date when contacted with good changes, so it shouldn't be going anywhere anytime soon.

First, a diagram of what you wish to accomplish:

                +------------------------------+
                |             Host             |
+----------+    | +--------+        +--------+ |
| Internet +------+ Ext IF +--------+ Int IF | |
+----------+    | | e1000g |        | gw0    | |
                | +--------+        +---+----+ |
                |                       |      |
                |  +--+-----------+     |      |
                |  |Z1|      VNIC1+-----+      |
                |  +--------------+     |      |
                |  +--------------+     |      |
                |  |Z2|      VNIC2+-----+      |
                |  +--------------+     |      |
                |  +--------------+     |      |
                |  |Z3|      VNIC3+-----+      |
                |  +--+-----------+            |
                |                              |
                +------------------------------+

In general, you must first understand that there is no one way to setup a nat'd internal network on SmartOS, but there are a few things that every method must tackle. Here is an overview of those things:

  1. An internal network must be established, and the global zone must be involved, since it's got control of the external interface and ip.
  2. You've got to decide between using an etherstub or not. There are pro's and con's to both choices, but they are fairly minor. Either way, the global zone needs an internal ip that acts as the gateway.
  3. NAT with ipnat is incredibly simple and can be read about here.. same is true of firewall rules with ipf. The basic premise here is that internal port forwarding uses rdr and external portmapping (the gateway maps an outbound port from an internal device to a different external port and keeps track of it's state, so that the return packet makes it to the internal ip that it should) is achieved with map lines.
  4. Making sure your configuration is persistent across reboots is that last concern with SmartOS. The easiest way is also the best way, which is using SMF to run a script that sets up your firewall and nat rules.

I mostly agree with Jeffrey's answer.

However I wrote the post you mentioned for that specific purpose (running smartos with 1 public IP) so here my suggestions if you applied my procedure.

http/https traffic:

  • Install nginx in a zone or kvm guest (let's say ip 10.0.0.2 port 80)
  • Add the port redirection in /etc/ipf/ipnat.conf (or NAT section in /opt/custom/share/svc/smartos_setup.sh)

    rdr e1000g0 0/0 port 80 -> 10.0.0.2 port 80 tcp 
    
  • Add the firewall rule in /etc/ipf/ipf.conf (or FW section in /opt/custom/share/svc/smartos_setup.sh)

    pass in quick on e1000g0 from any to e1000g0/32 port=80
    pass in quick on e1000g0 from any to 10.0.0.2 port=80
    
  • Reload ipfilter and ipnat rules:

    $ ipf -Fa -f /etc/ipf/ipf.conf
    $ ipnat -FC -f /etc/ipf/ipnat.conf
    
  • Once you can connect to the nginx instance, you can configure nginx to be a reverse proxy in front of other web servers on others hosts, see: http://wiki.nginx.org/NginxHttpProxyModule#proxy_pass

ssh traffic:

Same as above with port 2222 redirecting to 10.0.0.2:22, 2223 for 10.0.0.3:22 for instance:

rdr e1000g0 0/0 port 2222 -> 10.0.0.2 port 22 tcp
rdr e1000g0 0/0 port 2223 -> 10.0.0.3 port 22 tcp

if needed, be sure root login is enabled on the zone /etc/ssh/sshd_config (PermitRootLogin yes)