Blog

Two-factor authentication and encrypted access with Pomerium for SMB companies

Our clients often come to us with questions about more than just setting up IoT devices, monitoring assets, or generating reports. They also seek guidance on building their own cloud solutions, organizing failover clusters, and more. Recently, people have been asking how to organize access to cloud corporate resources, manage the rights of corporate users in the cloud, and implement two-factor authentication when accessing these resources, all at a minimal cost for SMB companies. In other words, a fast, beautiful, and inexpensive solution—Pomerium.

But what is the most common problem in any security project, whether it’s a small company or a huge corporation? The fact that improving security measures may come at the cost of user convenience. This can make users resist changes, increase internal support requests, blame the changes for problems, miss deadlines, or even simply refuse to use them. This is such a typical outcome that before each update you need to carefully think through every aspect before committing. Essentially, you want it to work simply, familiarly, and without changing your workflow.

It turns out that Navixy has some experience to solve this problem.

For the best results, it’s recommended that the level of security is acceptable, the complexity of operating the solution does not go off scale, and users don’t object to changes.

Benefits of Pomerium

Let's list what we get as a result of using Pomerium:

  1. Organize access to corporate resources that are accessible from the Internet without VPN, but are protected by encryption and two-factor authentication.
  2. Authorize users with SSO Google. Any provider that uses the OIDC protocol (OpenID Connect) can be used.
  3. Allow or deny access to corporate resources based on configured policies.
  4. Protect corporate TCP services, which may need access by logging in with a corporate Google Apps account. For example, accessing databases or servers using SSH.

In addition, Pomerium will also:

  1. Do all this without having to rely on any one external cloud vendor to, if necessary, move the solution to another cloud or run in several clouds at once.
  2. Do it all based on an Open Source solution. Even if there’s the future possibility of moving to a commercial license for convenience or scaling, you can start with Open Source for economy.

There are many such solutions. Why Pomerium? It’s an open, compact solution that’s easy to configure and use, and can also be quickly implemented for a small or medium-sized company.

How to install Pomerium

Pomerium can be installed in many ways, including by installing packages into the operating system, building from source, or running in a Docker or kubernetes container. In our opinion, the simplest thing is to use Docker, or rather Docker compose.

If access to corporate resources was previously organized via VPN, the access scheme would be as follows:

VPN access flow chart

The new scheme will use Google to provide the user with access to the resource they need:

Google access flow chart

All that remains is to select a server that will perform this function and install Docker on it.

curl -sSL https://get.docker.com/ | sh
sudo usermod -aG docker $USER
su $USER

Below is an example of a compose file to run a simple but quite functional option. Let’s Encrypt is used to generate certificates, so make sure that access to the Pomerium server is open on ports 80 and 443, and that DNS entries point to the desired server. In our example, the Pomerium server should be pointed to authenticate.gateway.example.com postgresql.gateway.example.com and http.gateway.example.com. These domains will need to be replaced with those used in the actual installation.

Make a folder in which Pomerium data will be stored.

cd ~
mkdir -p pomerium
cd pomerium

Create a docker-compose.yaml file with the following contents.

cat <<'EOF' >> docker-compose.yaml
version: "3"
services:
  pomerium:
    image: pomerium/pomerium:latest
    volumes:
      ## Mount your config file: https://www.pomerium.com/docs/reference/
      - ./config.yaml:/pomerium/config.yaml:ro
      - ./autocert:/data/autocert
    ports:
      - 80:80
      - 443:443
    depends_on:
      - db
  db:
    image: postgres:15.3-alpine
    restart: always
    environment:
    ## Set PG user: https://www.pomerium.com/docs/reference/
      - POSTGRES_USER=pomerium
      - POSTGRES_PASSWORD=pomerium
    ports:
      - '5432:5432'
    volumes:
      - ./db:/var/lib/postgresql/data

networks:
  default:
    ipam:
      config:
        - subnet: "172.31.255.0/24"
          gateway: "172.31.255.1"
EOF

Configuration is carried out in the ./config.yaml file in the directory with docker-compose.yaml.

cat <<'EOF' >> config.yaml
# See detailed configuration settings: https://www.pomerium.com/docs/reference/

#####################################################################
# If self-hosting, use the localhost authenticate service URL below #
# and remove the hosted URL.                                        #
#####################################################################
authenticate_service_url: https://authenticate.gateway.example.com
autocert: true
autocert_email: [email protected]

pomerium_debug: false

####################################################################################
# If self-hosting, you must configure an identity provider.                        #
# See identity provider settings: https://www.pomerium.com/docs/identity-providers/#
####################################################################################

# https://pomerium.com/reference/#routes
routes:
#HTTP
  - from: https://http.gateway.example.com
    to: http://http.internal.lan
    policy:
      - allow:
          and:
          - domain:
                is: example.com
#Database
  - from: tcp+https://postgresql.gateway.example.com:5432
    to: tcp://postgresql.internal.lan:5432
    policy:
      - allow:
          and:
          - domain:
                is: example.com


http_redirect_addr: :80
cookie_secret: cookie_secret

idp_provider: 'google'
idp_client_id: 'idp_client_id'
idp_client_secret: 'idp_client_secret'

databroker_storage_type: postgres
databroker_storage_connection_string: postgres://pomerium:pomerium@db/pomerium?sslmode=disable

timeout_idle: 1h
EOF

http.internal.lan and postgresql.internal.lan servers are within the corporate segment, which will be accessed from the Internet. Here is an example route and policy:

routes:
#HTTP
  - from: https://http.gateway.example.com
    to: http://http.internal.lan
    policy:
      - allow:
          and:
          - domain:
                is: example.com

When connecting to https://http.gateway.example.com, the user is authorized via Google with mail from the example.com domain, and then proxied to the internal resource http://http.internal.lan.

Instructions on how to make policies can be found here.

In order for everything to work, you just need to configure OAuth on the Google side. You will need to change idp_client_id and idp_client_secret in the configuration to the values generated by Google. It’s worth going here and doing everything according to the instructions.

Now let's check.

docker compose up

The server should start. To check, go to https://http.gateway.example.com and get a window with Google authorization. If authorization was successful, we are 80% done with the setup. All that remains is to make the necessary routes and policies.

It is worth adding a comment about access to TCP services.

#Database
  - from: tcp+https://postgresql.gateway.example.com:5432
    to: tcp://postgresql.internal.lan:5432
    policy:
      - allow:
          and:
          - domain:
                is: example.com

In this case, a special client is used that wraps TCP connections in https. To connect to the database, you need to install a client, create a connection for this route tcp+https://postgresql.gateway.example.com:5432 and connect through it. This is a little less obvious than using a VPN, but generally only requires setup once.

This is not an exhaustive description. You can run Pomerium in kubernetes, add fault tolerance and horizontal scaling for increased load, and use a different or your own OAuth provider. It seems like a small service, but it’s one with so many possibilities. I hope everything works out for you.

← Previous articleNext article →
Ready for the most innovative GPS tracking software?
SIGN UP
Recent posts