Skip to content

Commit

Permalink
Switch to using a Unix socket bind for API and Content services
Browse files Browse the repository at this point in the history
The use of a Unix socket between the deployed service and the reverse
proxy provides tighter security as the only users who can access the
socket are root and the configured SocketUser. The introduction of
a systemd socket with a ListenStream also provides automatic activation
of the underlying service and safer restarts.

This change is backwards incompatible as it removes the host and port parameters
for the API and Content services in favor of a single bind parameter for each.
  • Loading branch information
ehelms authored and ekohl committed Oct 15, 2020
1 parent 6f5b7c7 commit 04b9f5f
Show file tree
Hide file tree
Showing 9 changed files with 63 additions and 96 deletions.
4 changes: 2 additions & 2 deletions manifests/apache.pp
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@
) {
$vhost_priority = $pulpcore::apache_vhost_priority
$api_path = '/pulp/api/v3'
$api_base_url = "http://${pulpcore::api_host}:${pulpcore::api_port}"
$api_base_url = "unix://${pulpcore::api_socket_path}|http://${pulpcore::servername}"
$api_url = "${api_base_url}${api_path}"
$content_path = '/pulp/content'
$content_base_url = "http://${pulpcore::content_host}:${pulpcore::content_port}"
$content_base_url = "unix://${pulpcore::content_socket_path}|http://${pulpcore::servername}"
$content_url = "${content_base_url}${content_path}"

$docroot_directory = {
Expand Down
13 changes: 0 additions & 13 deletions manifests/config.pp
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,4 @@
mode => '0750',
}

selinux::port { 'pulpcore-api-port':
ensure => 'present',
seltype => 'pulpcore_port_t',
protocol => 'tcp',
port => $pulpcore::api_port,
}

selinux::port { 'pulpcore-content-port':
ensure => 'present',
seltype => 'pulpcore_port_t',
protocol => 'tcp',
port => $pulpcore::content_port,
}
}
20 changes: 6 additions & 14 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,11 @@
# apache_https_vhost, this will be used when attaching fragments to those
# vhosts. Note that this implies both vhosts need to have the same priority.
#
# @param api_host
# API service host
# @param api_socket_path
# Path where the Pulpcore API service is listening. This is a unix socket.
#
# @param api_port
# API service port
#
# @param content_host
# Content service host
#
# @param content_port
# Content service port
# @param content_socket_path
# Path where the Pulpcore Content service is listening. This is a unix socket.
#
# @param config_dir
# Pulp configuration directory. The settings.py file is created under this
Expand Down Expand Up @@ -158,10 +152,8 @@
Optional[Stdlib::Absolutepath] $apache_https_ca = undef,
Optional[Stdlib::Absolutepath] $apache_https_chain = undef,
String[1] $apache_vhost_priority = '10',
Stdlib::Host $api_host = '127.0.0.1',
Stdlib::Port $api_port = 24817,
Stdlib::Host $content_host = '127.0.0.1',
Stdlib::Port $content_port = 24816,
Stdlib::Absolutepath $api_socket_path = '/run/pulpcore-api.sock',
Stdlib::Absolutepath $content_socket_path = '/run/pulpcore-content.sock',
String $postgresql_db_name = 'pulpcore',
String $postgresql_db_user = 'pulp',
String $postgresql_db_password = extlib::cache_data('pulpcore_cache_data', 'db_password', extlib::random_password(32)),
Expand Down
14 changes: 14 additions & 0 deletions manifests/service.pp
Original file line number Diff line number Diff line change
@@ -1,12 +1,26 @@
# configure, enable, and start pulpcore services
# @api private
class pulpcore::service {
include apache

systemd::unit_file { 'pulpcore-api.socket':
content => template('pulpcore/pulpcore-api.socket.erb'),
active => true,
enable => true,
}

systemd::unit_file { 'pulpcore-api.service':
content => template('pulpcore/pulpcore-api.service.erb'),
active => true,
enable => true,
}

systemd::unit_file { 'pulpcore-content.socket':
content => template('pulpcore/pulpcore-content.socket.erb'),
active => true,
enable => true,
}

systemd::unit_file { 'pulpcore-content.service':
content => template('pulpcore/pulpcore-content.service.erb'),
active => true,
Expand Down
71 changes: 12 additions & 59 deletions spec/classes/pulpcore_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
{
'path' => '/pulp/content',
'provider' => 'location',
'proxy_pass' => [{'url' => 'http://127.0.0.1:24816/pulp/content'}],
'proxy_pass' => [{'url' => 'unix:///run/pulpcore-content.sock|http://foo.example.com/pulp/content'}],
'request_headers' => [
'unset X-CLIENT-CERT',
'set X-CLIENT-CERT "%{SSL_CLIENT_CERT}s" env=SSL_CLIENT_CERT',
Expand All @@ -79,7 +79,7 @@
{
'path' => '/pulp/content',
'provider' => 'location',
'proxy_pass' => [{'url' => 'http://127.0.0.1:24816/pulp/content'}],
'proxy_pass' => [{'url' => 'unix:///run/pulpcore-content.sock|http://foo.example.com/pulp/content'}],
'request_headers' => [
'unset X-CLIENT-CERT',
'set X-CLIENT-CERT "%{SSL_CLIENT_CERT}s" env=SSL_CLIENT_CERT',
Expand All @@ -88,7 +88,7 @@
{
'path' => '/pulp/api/v3',
'provider' => 'location',
'proxy_pass' => [{'url'=>'http://127.0.0.1:24817/pulp/api/v3'}],
'proxy_pass' => [{'url'=>'unix:///run/pulpcore-api.sock|http://foo.example.com/pulp/api/v3'}],
'request_headers' => [
'unset REMOTE_USER',
'set REMOTE_USER "%{SSL_CLIENT_S_DN_CN}s" env=SSL_CLIENT_S_DN_CN',
Expand All @@ -98,7 +98,7 @@
.with_proxy_pass([
{
'path' => '/assets/',
'url' => 'http://127.0.0.1:24817/assets/',
'url' => 'unix:///run/pulpcore-api.sock|http://foo.example.com/assets/',
},
])
is_expected.not_to contain_apache__vhost__fragment('pulpcore-https-pulpcore')
Expand Down Expand Up @@ -185,7 +185,6 @@
it do
is_expected.to compile.with_all_deps
is_expected.not_to contain_file('/var/lib/pulp/docroot')
is_expected.not_to contain_class('apache')
is_expected.not_to contain_apache__vhost('pulpcore')
is_expected.not_to contain_apache__vhost('pulpcore-https')
is_expected.not_to contain_selinux__boolean('httpd_can_network_connect')
Expand Down Expand Up @@ -228,8 +227,8 @@
<Location "/pulp/content">
RequestHeader unset X-CLIENT-CERT
RequestHeader set X-CLIENT-CERT "%{SSL_CLIENT_CERT}s" env=SSL_CLIENT_CERT
ProxyPass http://127.0.0.1:24816/pulp/content
ProxyPassReverse http://127.0.0.1:24816/pulp/content
ProxyPass unix:///run/pulpcore-content.sock|http://foo.example.com/pulp/content
ProxyPassReverse unix:///run/pulpcore-content.sock|http://foo.example.com/pulp/content
</Location>
CONTENT
)
Expand All @@ -245,19 +244,19 @@
<Location "/pulp/content">
RequestHeader unset X-CLIENT-CERT
RequestHeader set X-CLIENT-CERT "%{SSL_CLIENT_CERT}s" env=SSL_CLIENT_CERT
ProxyPass http://127.0.0.1:24816/pulp/content
ProxyPassReverse http://127.0.0.1:24816/pulp/content
ProxyPass unix:///run/pulpcore-content.sock|http://foo.example.com/pulp/content
ProxyPassReverse unix:///run/pulpcore-content.sock|http://foo.example.com/pulp/content
</Location>
<Location "/pulp/api/v3">
RequestHeader unset REMOTE_USER
RequestHeader set REMOTE_USER "%{SSL_CLIENT_S_DN_CN}s" env=SSL_CLIENT_S_DN_CN
ProxyPass http://127.0.0.1:24817/pulp/api/v3
ProxyPassReverse http://127.0.0.1:24817/pulp/api/v3
ProxyPass unix:///run/pulpcore-api.sock|http://foo.example.com/pulp/api/v3
ProxyPassReverse unix:///run/pulpcore-api.sock|http://foo.example.com/pulp/api/v3
</Location>
ProxyPass /assets/ http://127.0.0.1:24817/assets/
ProxyPassReverse /assets/ http://127.0.0.1:24817/assets/
ProxyPass /assets/ unix:///run/pulpcore-api.sock|http://foo.example.com/assets/
ProxyPassReverse /assets/ unix:///run/pulpcore-api.sock|http://foo.example.com/assets/
CONTENT
)
end
Expand Down Expand Up @@ -285,52 +284,6 @@
end
end

context 'with custom ports' do
let :params do
{
api_port: 24819,
content_port: 24818,
}
end

it do
is_expected.to compile.with_all_deps
is_expected.to contain_selinux__port('pulpcore-api-port')
.with_port(24819)
is_expected.to contain_selinux__port('pulpcore-content-port')
.with_port(24818)
is_expected.to contain_systemd__unit_file('pulpcore-api.service')
.with_content(%r{--bind '127.0.0.1:24819'})
is_expected.to contain_systemd__unit_file('pulpcore-content.service')
.with_content(%r{--bind '127.0.0.1:24818'})
is_expected.to contain_apache__vhost('pulpcore')
.with_directories([
{
'provider' => 'Directory',
'path' => '/var/lib/pulp/docroot',
'options' => ['-Indexes', '-FollowSymLinks'],
'allow_override' => ['None'],
},
{
'path' => '/pulp/content',
'provider' => 'location',
'proxy_pass' => [{'url' => 'http://127.0.0.1:24818/pulp/content'}],
'request_headers' => [
'unset X-CLIENT-CERT',
'set X-CLIENT-CERT "%{SSL_CLIENT_CERT}s" env=SSL_CLIENT_CERT',
],
},
])
is_expected.to contain_apache__vhost('pulpcore-https')
.with_proxy_pass([
{
'path' => '/assets/',
'url' => 'http://127.0.0.1:24819/assets/',
},
])
end
end

context 'with external postgresql' do
let :params do
{
Expand Down
9 changes: 5 additions & 4 deletions templates/pulpcore-api.service.erb
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
[Unit]
Description=Pulp WSGI Server
After=network-online.target
Wants=network-online.target
Description=Pulp API Server
After=network.target
Requires=pulpcore-api.socket

[Service]
type=notify
Environment="DJANGO_SETTINGS_MODULE=pulpcore.app.settings"
Environment="PULP_SETTINGS=<%= scope['pulpcore::settings_file'] %>"
User=<%= scope['pulpcore::user'] %>
Group=<%= scope['pulpcore::group'] %>
WorkingDirectory=<%= scope['pulpcore::user_home'] %>
RuntimeDirectory=pulpcore-api
ExecStart=/usr/libexec/pulpcore/gunicorn pulpcore.app.wsgi:application \
--bind '<%= scope['pulpcore::api_host'] %>:<%= scope['pulpcore::api_port'] %>' \
--access-logfile -
ExecReload=/bin/kill -s HUP $MAINPID
ProtectSystem=full
PrivateTmp=yes
PrivateDevices=yes
Expand Down
10 changes: 10 additions & 0 deletions templates/pulpcore-api.socket.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Pulp API Server socket

[Socket]
ListenStream=<%= scope['pulpcore::api_socket_path'] %>
SocketUser=<%= scope['apache::user'] %>
SocketMode=0600

[Install]
WantedBy=sockets.target
8 changes: 4 additions & 4 deletions templates/pulpcore-content.service.erb
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
[Unit]
Description=Pulp Content App
After=network-online.target
Wants=network-online.target
Requires=pulpcore-content.socket
After=network.target

[Service]
type=notify
Environment="DJANGO_SETTINGS_MODULE=pulpcore.app.settings"
Environment="PULP_SETTINGS=<%= scope['pulpcore::settings_file'] %>"
User=<%= scope['pulpcore::user'] %>
Group=<%= scope['pulpcore::group'] %>
WorkingDirectory=<%= scope['pulpcore::user_home'] %>
RuntimeDirectory=pulpcore-content
ExecStart=/usr/libexec/pulpcore/gunicorn pulpcore.content:server \
--bind '<%= scope['pulpcore::content_host'] %>:<%= scope['pulpcore::content_port'] %>' \
--worker-class 'aiohttp.GunicornWebWorker' \
-w 2 \
--access-logfile -

ExecReload=/bin/kill -s HUP $MAINPID
SyslogIdentifier=pulpcore-content

# This provides reconnect support for PostgreSQL and Redis. Without reconnect support, if either
Expand Down
10 changes: 10 additions & 0 deletions templates/pulpcore-content.socket.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
[Unit]
Description=Pulp Content App socket

[Socket]
ListenStream=<%= scope['pulpcore::content_socket_path'] %>
SocketUser=<%= scope['apache::user'] %>
SocketMode=0600

[Install]
WantedBy=sockets.target

0 comments on commit 04b9f5f

Please sign in to comment.