Puma production deployment port


during work on the SELinux policy changes, I’ve noticed that Puma listens on 3000 tcp by default. This port is already assigned to ntop_port_t for application ntop. It is also used by few other apps [1] and it appears to be the default Rails development port.

Since there is still some time to change this, I would like to open up discussion about picking a different higher-range port that is not used officially, unofficially or even assigned in SELinux base policy. The only reason I have is that reusing SELinux port assignments can bring huge pains when these get reassigned in the base policy. @packaging

My preference would actually be to use a unix socket instead of a TCP port. The benefit is that we can enforce that only Apache can talk to it. This takes away the risk where anyone who can talk to localhost:3000 can impersonate any client (by spoofing headers). It’s been on my wish list but didn’t manage to get to it in time. If it makes the SELinux policy easier, it’s a good reason to push it into 2.1 rather than 2.2.

1 Like

As much as I would love to see UNIX domain socket, I would not like to be the reason why something gets delayed. Let me know if you manage it to squeeze it. If not, I am adding port 3000 for now. Or if we agree here I can create a new SELinux port reservation for a particular number we choose.

Is there a reason why we spawn rails helper instead of puma directly?

It looks like currently something in the stack calls shell, therefore in our new SELinux policy I need to allow shell spawning which is sub-ideal. I am hoping that it’s Rails spawning Puma so eliminating this in the chain could simplify the SELinux policy.

This way I got it all to work, including socket activation but I’ll admit I’m not sure what the exact difference is between rails server and puma other than that rails server provides some wrappers as well.

It can also be in SCL helpers. From my Foreman 2.0 install:

$ ps auxf
# <snip>
foreman   5986  0.0  0.0   4356   560 ?        Ss   May16   0:00 /usr/bin/scl enable tfm rails server --environment $FOREMAN_ENV --port $FOREMAN_PORT --binding $FOREMAN_BIND
foreman   5987  0.0  0.0 113284  1428 ?        S    May16   0:00  \_ /bin/bash /var/tmp/sclIV6Zq0
foreman   6001  0.4  8.7 1841060 713716 ?      Sl   May16  12:24      \_ puma 3.11.4 (tcp:// [foreman]
# <snip>

Oh looks like we know more now. This is sidekick:

# cat /var/tmp/sclPZHShi
eval "SCLS=( ${X_SCLS[*]} )"
/usr/bin/scl_enabled tfm
if [ $? != 0 ]; then
  export X_SCLS=$(printf '%q ' "${SCLS[@]}")
. /opt/theforeman/tfm//enable
sidekiq -e production -r /usr/share/foreman/extras/dynflow-sidekiq.rb -C /etc/foreman/dynflow/worker-hosts-queue.yml

Looks like we spawn it from Rails. Why? It should be much better to have it as a separate service.

Wait, this is a separate service. I see it separately:

foreman   1227  0.0  0.0   4356   584 ?        Ss   10:26   0:00 /usr/bin/scl enable tfm sidekiq -e production -r /usr/share/foreman/extras/dynflow-sidekiq.rb -C /etc/foreman/dynflow/worker-h
foreman   1230  0.0  0.0 113284  1472 ?        S    10:26   0:00  \_ /bin/bash /var/tmp/sclPZHShi
foreman   1671  0.3  4.2 972624 545000 ?       Sl   10:26   1:17      \_ sidekiq 5.2.7  [0 of 5 busy]
foreman   1228  0.0  0.0   4356   580 ?        Ss   10:26   0:00 /usr/bin/scl enable tfm sidekiq -e production -r /usr/share/foreman/extras/dynflow-sidekiq.rb -C /etc/foreman/dynflow/orchestr
foreman   1233  0.0  0.0 113284  1472 ?        S    10:26   0:00  \_ /bin/bash /var/tmp/sclK73gxl
foreman   1672  0.3  4.2 967056 550132 ?       Sl   10:26   1:13      \_ sidekiq 5.2.7  [0 of 1 busy]
foreman   1231  0.0  0.0   4356   584 ?        Ss   10:26   0:00 /usr/bin/scl enable tfm sidekiq -e production -r /usr/share/foreman/extras/dynflow-sidekiq.rb -C /etc/foreman/dynflow/worker.y
foreman   1235  0.0  0.0 113284  1468 ?        S    10:26   0:00  \_ /bin/bash /var/tmp/sclZyxPol
foreman   1670  0.3  4.2 973672 545772 ?       Sl   10:26   1:18      \_ sidekiq 5.2.7  [0 of 5 busy]
foreman   8074  3.2  3.8 1014624 500256 ?      Ssl  16:00   0:46 puma 4.3.3 (tcp:// [foreman]
foreman   8119  0.1  3.9 1896360 514028 ?      Sl   16:01   0:02  \_ puma: cluster worker 0: 8074 [foreman]
foreman   8126  0.0  3.8 1753996 499292 ?      Sl   16:01   0:00  \_ puma: cluster worker 1: 8074 [foreman]

Your case is probably a development mode?

That is a generated wrapper from scl enable, we have no control over that. We might be able to call things using /usr/bin/tfm-ruby like we did with puma.

It is a separate service, but needs to run with the Rails code loaded. All our jobs assume the Foreman application is loaded. See systemctl status dynflow-sidekiq@*

No, it was the result of

To get socket activation to work, I needed to get rid of the additional forking that the SCL helper introduced. An additional benefit is fewer processes running. As I mentioned, my server is on 2.0.

Ok, that explains the shell.

I have another issue explained above: Ruby on Rails (puma) process creates UNIX sockets that I don’t know what are for. Puma devs already confirmed and I have tested with “Hello World” puma application that it’s not Puma. It must be some gem: https://github.com/puma/puma/issues/2272

Any idea? I am going to research this today.

Further research shows that the reason is really socket activation! The communication is via UNIX sockets, hence the name :slight_smile: