diff --git a/.assets/bastion.jpg b/.assets/bastion.jpg
index 6196fe69..c92ff70c 100644
Binary files a/.assets/bastion.jpg and b/.assets/bastion.jpg differ
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index bb3b295d..d73fc798 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -1,6 +1,7 @@
name: Build & Release
on:
+ workflow_dispatch:
push:
tags:
- '*'
diff --git a/.goreleaser.yml b/.goreleaser.yml
index 73614b80..947a8a50 100644
--- a/.goreleaser.yml
+++ b/.goreleaser.yml
@@ -31,6 +31,12 @@ nfpms:
dependencies:
- systemd
+ recommends:
+ - sqlite3
+
+ suggests:
+ - mariadb
+
provides:
- sshportal
@@ -40,7 +46,14 @@ nfpms:
- src: packaging/etc/
dst: /etc/
type: tree
+ - src: packaging/selinux/sshportal.pp
+ dst: /usr/share/selinux/packages/sshportal.pp
scripts:
+ preinstall: "packaging/preinstall.sh"
postinstall: "packaging/postinstall.sh"
- postremove: "packaging/postremove.sh"
\ No newline at end of file
+ postremove: "packaging/postremove.sh"
+
+ deb:
+ scripts:
+ templates: packaging/deb/template
\ No newline at end of file
diff --git a/README.md b/README.md
index 85468d28..8dfaf814 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,7 @@
+
+

+
+
# sshportal
[](https://goreportcard.com/report/moul.io/sshportal)
@@ -14,21 +18,28 @@ Jump host/Jump server without the jump, a.k.a Transparent SSH bastion

+[](https://github.com/alterway/sshportal/blob/master/LICENSE)
+[](https://github.com/alterway/sshportal/releases)
+
+## IMPORTANT NOTE
+
+**The [original project](https://github.com/moul/sshportal) is no longer being maintained. This fork includes important security fixes, some bugfixes and features but it is on MAINTENANCE mode and only security issues and major bugs will be fixed. You should consider using [Teleport](https://github.com/gravitational/teleport) instead.**
---
-## Contents
+
+
+---
-- [Installation and usage](#installation-and-usage)
+- [Installation and usage](#installation)
+- [Quick Start](#quick-start)
- [Features and limitations](#features-and-limitations)
- [Backup / Restore](#backup--restore)
-- [built-in shell](#built-in-shell)
-- [Shell commands](#shell-commands)
+- [Built-in shell](#built-in-shell)
- [Healthcheck](#healthcheck)
-- [portal alias (.ssh/config)](#portal-alias-sshconfig)
-- [Scaling](#scaling)
+- [Portal alias (.ssh/config)](#portal-alias-sshconfig)
- [Under the hood](#under-the-hood)
- [Testing](#testing)
@@ -36,7 +47,7 @@ Jump host/Jump server without the jump, a.k.a Transparent SSH bastion
---
-## Installation and usage
+### Installation
Packaged installation is privileged as it comes with a hardened systemd service config.
@@ -48,7 +59,7 @@ Packaged installation is privileged as it comes with a hardened systemd service
apt install ./sshportal.deb
```
-This will install sshportal as a systemd service, configure logrotate to keep 1 year of audit logs and add a dedicated cron for session logs. See [`packaging`](https://github.com/alterway/sshportal/tree/master/packaging).
+This will install sshportal as a systemd service, configure logrotate to keep 1 year of audit logs and add a systemd timer for purging session logs. See [`packaging`](https://github.com/alterway/sshportal/tree/master/packaging).
2) Get the invite token
@@ -77,6 +88,64 @@ ssh sshportal@localhost -p 2222
An [automated build is setup on the Github registry](https://github.com/alterway/sshportal/pkgs/container/sshportal).
+Packaged installation (`.deb` & `.rpm`) is privileged as it comes with a hardened systemd service and a SELinux module if you have enfored SELinux on your GNU/Linux distribution.
+
+Get the latest version [here](https://github.com/alterway/sshportal/releases)
+
+**Note :** By default, your package manager will automatically install `sqlite` (recommended dependency)
+
+This installation will install sshportal as a systemd service, configure logrotate to keep 1 year of audit logs and add a dedicated cron for session logs. See [`packaging`](https://github.com/alterway/sshportal/tree/master/packaging).
+
+If mariadb is selected during the install, it will also automatically create the `sshportal` database if it doesn't exist.
+
+
+Show Debian-based distributions instructions
+
+```bash
+apt install ./sshportal_x.x.x_xxx.deb
+```
+You will be asked if you want to use `mariadb` instead of `sqlite` (default). Make sure to install `mariadb-server` before as the package is not listed as a hard dependency in the [control file](https://github.com/alterway/sshportal/blob/debian/.goreleaser.yml#L31).
+
+To install SSHportal with mariadb:
+
+```bash
+apt install -y mariadb-server
+DEBIAN_FRONTEND=noninteractive SSHPORTAL_MARIADB_SETUP=true apt install --no-install-recommends -y ./sshportal_x.x.x_xxx.deb
+```
+
+If you want to stick with sqlite, you just have to do this:
+
+```bash
+DEBIAN_FRONTEND=noninteractive apt install -y ./sshportal_x.x.x_xxx.deb
+```
+
+
+
+
+Show RedHat-based distributions instructions
+
+Make sure to install `mariadb-server` before if you want to use it as this package is not listed as a hard dependency in the [control file](https://github.com/alterway/sshportal/blob/debian/.goreleaser.yml#L31).
+
+There is no debconf in RedHat distribution so if you want an automatic mariadb setup you need to install `sshportal` with :
+
+```bash
+dnf install -y mariadb-server
+SSHPORTAL_MARIADB_SETUP=true dnf install --setopt=install_weak_deps=False ./sshportal_x.x.x_xxx.rpm
+```
+
+If you want to stick with sqlite, you just have to do this:
+
+```bash
+dnf install -y ./sshportal_x.x.x_xxx.rpm
+```
+
+
+
+
+Docker instructions
+
+An [automated build is setup on the Github registry](https://github.com/alterway/sshportal/pkgs/container/sshportal).
+
```bash
# Start a server in background
# mount `pwd` to persist the sqlite database file
@@ -87,8 +156,38 @@ docker logs -f sshportal
```
### Quick start
+
+
+---
+
+### Quick start
+
+Get the invite token in stdout or `/var/log/sshportal/audit/audit.log` if installed from a package manager :
-Create your first host
+```bash
+2023/09/01 15:03:18 info: system migrated
+2023/09/01 15:03:18 info: 'sshportal' user created. Run 'ssh localhost -p 2222 -l invite:6tUguNFYxeOxdx0N' to associate your public key with this account
+2023/09/01 15:03:18 info: SSH Server accepting connections on :2222, idle-timout=0s
+```
+
+3) Make sure you have a ssh key pair and associate your public key to the bastion
+
+```bash
+ssh localhost -p 2222 -l invite:xxxxxxx
+
+Welcome sshportal!
+
+Your key is now associated with the user "sshportal@localhost".
+```
+
+4) Your first user is the admin. To access to the console, connect like a normal server
+
+```bash
+ssh sshportal@localhost -p 2222
+```
+
+
+5) Create your first host
```console
config> host create bart@foo.example.org
@@ -96,7 +195,7 @@ config> host create bart@foo.example.org
config>
```
-List hosts
+6) List hosts
```console
config> host ls
@@ -108,6 +207,7 @@ config>
```
Add the `host` key to the server
+7) Add the `host` key to the server
```console
config> host ls
@@ -125,14 +225,18 @@ config> key ls
ssh bart@foo.example.org "$(ssh sshportal@localhost -p 2222 key setup host)"
```
-Profit
+```console
+ssh bart@foo.example.org "$(ssh sshportal@localhost -p 2222 key setup host)"
+```
+
+8) Profit
```console
ssh localhost -p 2222 -l foo
bart@foo>
```
-Invite friends
+9) Invite friends
*This command doesn't create a user on the remote server, it only creates an account in the sshportal database.*
@@ -147,7 +251,7 @@ Demo gif:
---
-## Features and limitations
+### Features and limitations
* Single autonomous binary (~20Mb) with no runtime dependencies (except glibc)
* Portable / Cross-platform (regularly tested on linux and OSX/darwin)
@@ -186,13 +290,13 @@ Demo gif:
**(Known) limitations**
-* Does not work (yet?) with [`mosh`](https://mosh.org/)
+* Does not work with [`mosh`](https://mosh.org/)
* It is not possible for a user to access a host with the same name as the user. This is easily circumvented by changing the user name, especially since the most common use cases does not expose it.
* It is not possible to access a host named `healthcheck` as this is a built-in command.
---
-## Backup / Restore
+### Backup / Restore
sshportal embeds built-in backup/restore methods which basically import/export JSON objects:
@@ -218,7 +322,7 @@ cp sshportal.db sshportal.db.bkp
---
-## built-in shell
+### Built-in shell
`sshportal` embeds a configuration CLI.
@@ -235,84 +339,11 @@ You can enter in interactive mode using this syntax: `ssh root@portal.example.or

---
-## Shell commands
-
-```sh
-# acl management
-acl help
-acl create [-h] [--hostgroup=HOSTGROUP...] [--usergroup=USERGROUP...] [--pattern=] [--comment=] [--action=] [--weight=value]
-acl inspect [-h] ACL...
-acl ls [-h] [--latest] [--quiet]
-acl rm [-h] ACL...
-acl update [-h] [--comment=] [--action=] [--weight=] [--assign-hostgroup=HOSTGROUP...] [--unassign-hostgroup=HOSTGROUP...] [--assign-usergroup=USERGROUP...] [--unassign-usergroup=USERGROUP...] ACL...
-
-# config management
-config help
-config backup [-h] [--indent] [--decrypt]
-config restore [-h] [--confirm] [--decrypt]
-
-# event management
-event help
-event ls [-h] [--latest] [--quiet]
-event inspect [-h] EVENT...
-
-# host management
-host help
-host create [-h] [--name=] [--password=] [--comment=] [--key=KEY] [--group=HOSTGROUP...] [--hop=HOST] [--logging=MODE] [:]@[:]
-host inspect [-h] [--decrypt] HOST...
-host ls [-h] [--latest] [--quiet]
-host rm [-h] HOST...
-host update [-h] [--name=] [--comment=] [--key=KEY] [--assign-group=HOSTGROUP...] [--unassign-group=HOSTGROUP...] [--logging-MODE] [--set-hop=HOST] [--unset-hop] [--reset] HOST...
-
-# hostgroup management
-hostgroup help
-hostgroup create [-h] [--name=] [--comment=]
-hostgroup inspect [-h] HOSTGROUP...
-hostgroup ls [-h] [--latest] [--quiet]
-hostgroup rm [-h] HOSTGROUP...
-
-# key management
-key help
-key create [-h] [--name=] [--type=] [--length=] [--comment=]
-key import [-h] [--name=] [--comment=]
-key inspect [-h] [--decrypt] KEY...
-key ls [-h] [--latest] [--quiet]
-key rm [-h] KEY...
-key setup [-h] KEY
-key show [-h] KEY
-
-# session management
-session help
-session ls [-h] [--latest] [--quiet]
-session inspect [-h] SESSION...
-
-# user management
-user help
-user invite [-h] [--name=] [--comment=] [--group=USERGROUP...]
-user inspect [-h] USER...
-user ls [-h] [--latest] [--quiet]
-user rm [-h] USER...
-user kick [-h] USER
-user ban [-h] USER
-user update [-h] [--name=] [--email=] [--set-admin] [--unset-admin] [--assign-group=USERGROUP...] [--unassign-group=USERGROUP...] USER...
-
-# usergroup management
-usergroup help
-usergroup create [-h] [--name=] [--comment=]
-usergroup inspect [-h] USERGROUP...
-usergroup ls [-h] [--latest] [--quiet]
-usergroup rm [-h] USERGROUP...
-
-# other
-exit [-h]
-help, h
-info [-h]
-version [-h]
-```
+See [Documentation](https://github.com/alterway/sshportal/wiki/Documentation) for the list of shell commands.
---
-## Healthcheck
+### Healthcheck
By default, `sshportal` will return `OK` to anyone sshing using the `healthcheck` user without checking for authentication.
@@ -346,12 +377,14 @@ config>
---
## Portal alias (.ssh/config)
+### Portal alias (.ssh/config)
Edit your `~/.ssh/config` file (create it first if needed)
```ini
Host portal
User root # or 'sshportal' if you use the packaged binary
+ User root # or 'sshportal' if you use the packaged sshportal
Port 2222 # portal port
HostName 127.0.0.1 # portal hostname
```
@@ -385,6 +418,7 @@ See [examples/mysql](http://github.com/alterway/sshportal/tree/master/examples/m
---
## Under the hood
+### Under the hood
* Docker first (used in dev, tests, by the CI and in production)
* Backed by (see [dep graph](https://godoc.org/github.com/alterway/sshportal?import-graph&hide=2)):
@@ -405,7 +439,7 @@ See [examples/mysql](http://github.com/alterway/sshportal/tree/master/examples/m
---
-## Testing
+### Testing
[Install golangci-lint](https://golangci-lint.run/usage/install/#local-installation) and run this in project root:
```
diff --git a/packaging/deb/template b/packaging/deb/template
new file mode 100644
index 00000000..977bce84
--- /dev/null
+++ b/packaging/deb/template
@@ -0,0 +1,4 @@
+Template: sshportal_mariadb_database
+Type: boolean
+Description: Use mariadb as database instead of Sqlite?
+Default: false
\ No newline at end of file
diff --git a/packaging/etc/logrotate.d/sshportal b/packaging/etc/logrotate.d/sshportal
index bba95e1e..a5ec2f8e 100644
--- a/packaging/etc/logrotate.d/sshportal
+++ b/packaging/etc/logrotate.d/sshportal
@@ -1,13 +1,12 @@
-/var/log/sshportal/audit.log {
+/var/log/sshportal/audit/audit.log {
daily
missingok
rotate 365
compress
notifempty
- create 640 root root
dateext
dateformat -%Y-%m-%d
postrotate
- invoke-rc.d rsyslog rotate > /dev/null
+ systemctl kill -s HUP rsyslog.service
endscript
}
\ No newline at end of file
diff --git a/packaging/etc/systemd/system/sshportal.service b/packaging/etc/systemd/system/sshportal.service
index 90415baf..404e448c 100644
--- a/packaging/etc/systemd/system/sshportal.service
+++ b/packaging/etc/systemd/system/sshportal.service
@@ -1,17 +1,15 @@
[Unit]
After=ssh.service
+Wants=sshportal_clean_session_logs.timer
[Service]
Type=exec
DynamicUser=yes
User=sshportal
-#Restart=on-failure
-RestartSec=10s
StandardOutput=append:/var/log/sshportal/audit/audit.log
LogsDirectory=sshportal
StateDirectory=sshportal
Environment=SSHPORTAL_LOGS_LOCATION=/var/log/sshportal/session
-Environment=SSHPORTAL_DATABASE_URL=/var/lib/sshportal/sshportal.db
ExecStartPre=mkdir -p /var/log/sshportal/audit
ExecStart=/usr/bin/sshportal server
ExecStop=/bin/kill -SIGTERM $MAINPID
diff --git a/packaging/etc/systemd/system/sshportal_clean_session_logs.service b/packaging/etc/systemd/system/sshportal_clean_session_logs.service
new file mode 100644
index 00000000..32003cf9
--- /dev/null
+++ b/packaging/etc/systemd/system/sshportal_clean_session_logs.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Cleanup of SSHportal session logs
+
+[Service]
+Type=oneshot
+ExecStart=find /var/log/sshportal/session/ -ctime +365 -type f -delete
+
+[Install]
+WantedBy=default.target
\ No newline at end of file
diff --git a/packaging/etc/systemd/system/sshportal_clean_session_logs.timer b/packaging/etc/systemd/system/sshportal_clean_session_logs.timer
new file mode 100644
index 00000000..2b4a64b4
--- /dev/null
+++ b/packaging/etc/systemd/system/sshportal_clean_session_logs.timer
@@ -0,0 +1,10 @@
+[Unit]
+Description=Cleanup of SSHportal session logs
+ConditionPathIsDirectory=/var/log/sshportal/session/
+
+[Timer]
+OnCalendar=weekly
+OnUnitActiveSec=1d
+
+[Install]
+WantedBy=timers.target
\ No newline at end of file
diff --git a/packaging/postinstall.sh b/packaging/postinstall.sh
index 63a2e09d..897b5352 100755
--- a/packaging/postinstall.sh
+++ b/packaging/postinstall.sh
@@ -1,7 +1,42 @@
-#!/bin/sh
+#!/bin/sh -e
+
+mkdir -p /etc/systemd/system/sshportal.service.d/
+
+if [ -f /tmp/sshportal_mariadb ]; then
+ SOCKET="$(mysqladmin variables | grep ".sock " | awk '{print $4}')"
+ readonly SOCKET
+
+tee /etc/systemd/system/sshportal.service.d/custom.conf >/dev/null 2>&1 << END
+[Service]
+StateDirectory=
+Environment=SSHPORTAL_DB_DRIVER=mysql
+Environment=SSHPORTAL_DATABASE_URL=sshportal@unix($SOCKET)/sshportal?charset=utf8&parseTime=true&loc=Local
+END
+ rm -f /tmp/sshportal_mariadb
+else
+
+tee /etc/systemd/system/sshportal.service.d/custom.conf >/dev/null 2>&1 << END
+[Service]
+Environment=SSHPORTAL_DB_DRIVER=sqlite3
+Environment=SSHPORTAL_DATABASE_URL=/var/lib/sshportal/sshportal.db
+END
+
+fi
+
+if command -v selinuxenabled >/dev/null 2>&1; then
+ semodule -i /usr/share/selinux/packages/sshportal.pp
+ restorecon -F -R /usr/bin/sshportal
+fi
mkdir -p /var/log/sshportal/audit
-echo "0 1 * * 0 root find /var/log/sshportal/session/ -ctime +365 -type f -delete" > /etc/cron.d/sshportal
systemctl daemon-reload
-systemctl enable sshportal
-systemctl start sshportal
+
+# LogsDirectory, StateDirectory are created by systemd
+if command -v selinuxenabled >/dev/null 2>&1; then
+ systemctl enable --now sshportal >/dev/null 2>&1 # this will fail because of SELinux on first install
+ restorecon -F -R /var/log/sshportal
+ [ -d /var/lib/sshportal ] && restorecon -F -R /var/lib/sshportal
+fi
+
+systemctl enable --now sshportal
+systemctl enable --now sshportal_clean_session_logs.timer
\ No newline at end of file
diff --git a/packaging/postremove.sh b/packaging/postremove.sh
index 6ea485d6..666a2680 100755
--- a/packaging/postremove.sh
+++ b/packaging/postremove.sh
@@ -1,6 +1,20 @@
-#!/bin/sh
+#!/bin/sh -e
+# shellcheck source=/dev/null
+
+if grep -q "debian" /etc/os-release; then
+ . /usr/share/debconf/confmodule
+ db_purge
+fi
+
+if command -v semodule >/dev/null 2>&1; then
+ semodule -l | grep -q sshportal && semodule -r sshportal
+fi
systemctl is-active --quiet sshportal && systemctl stop sshportal
-rm -f /etc/cron.d/sshportal
+rm -f /etc/logrotate.d/sshportal || true
+[ -d /etc/systemd/system/sshportal.service.d ] && rm -rf /etc/systemd/system/sshportal.service.d
+
+grep -q sshportal /etc/passwd && userdel sshportal
systemctl daemon-reload
-systemctl reset-failed
\ No newline at end of file
+systemctl reset-failed
+
diff --git a/packaging/preinstall.sh b/packaging/preinstall.sh
new file mode 100755
index 00000000..f8684031
--- /dev/null
+++ b/packaging/preinstall.sh
@@ -0,0 +1,42 @@
+#!/bin/sh -e
+# shellcheck source=/dev/null
+
+MARIADB_INSTALLED="false"
+RET="false"
+readonly BYELLOW='\033[1;33m'
+readonly BRED='\033[1;31m'
+readonly NC='\033[0m'
+
+if grep -q "fedora" /etc/os-release; then
+ [ "$1" -ne 1 ] && exit 0 # run this script only on install
+ rpm -q mariadb-server >/dev/null 2>&1 && MARIADB_INSTALLED="true"
+fi
+
+if grep -q "debian" /etc/os-release; then
+ [ "$1" != "install" ] && exit 0 # run this script only on install
+
+ dpkg -s mariadb-server >/dev/null 2>&1 && MARIADB_INSTALLED="true"
+
+ . /usr/share/debconf/confmodule
+ db_input high sshportal_mariadb_database || true
+ db_go || true
+ db_get sshportal_mariadb_database
+fi
+
+if [ "$RET" = "true" ] || [ "$SSHPORTAL_MARIADB_SETUP" = "true" ]; then
+
+ if [ "$MARIADB_INSTALLED" = "false" ]; then
+ printf "${BRED}%s %s${NC}\n" "ERROR: Please install mariadb-server if you don't want to use Sqlite"
+ exit 2
+ fi
+
+ useradd -rd /nonexistent -s /usr/sbin/nologin sshportal # can't use systemd dynamic user to access the unix socket
+ systemctl enable --now mariadb
+ mariadb -e "CREATE DATABASE sshportal CHARACTER SET utf8;" || printf "${BYELLOW}%s %s${NC}\n" "WARNING: sshportal database already exists"
+ mariadb -e "GRANT ALL on sshportal.* to 'sshportal'@'localhost' identified via unix_socket;"
+
+ if grep -q "Debian" /etc/os-release; then
+ db_go || true
+ fi
+ touch /tmp/sshportal_mariadb
+fi
diff --git a/packaging/selinux/sshportal.fc b/packaging/selinux/sshportal.fc
new file mode 100644
index 00000000..95bdf9fb
--- /dev/null
+++ b/packaging/selinux/sshportal.fc
@@ -0,0 +1,5 @@
+/usr/bin/sshportal -- gen_context(system_u:object_r:sshportal_exec_t,s0)
+
+/var/lib/sshportal(/.*)? gen_context(system_u:object_r:sshportal_var_lib_t,s0)
+
+/var/log/sshportal(/.*)? gen_context(system_u:object_r:sshportal_log_t,s0)
\ No newline at end of file
diff --git a/packaging/selinux/sshportal.pp b/packaging/selinux/sshportal.pp
new file mode 100644
index 00000000..b607f96e
Binary files /dev/null and b/packaging/selinux/sshportal.pp differ
diff --git a/packaging/selinux/sshportal.te b/packaging/selinux/sshportal.te
new file mode 100644
index 00000000..0f587007
--- /dev/null
+++ b/packaging/selinux/sshportal.te
@@ -0,0 +1,64 @@
+policy_module(sshportal, 1.0.0)
+
+gen_require(
+ type sysctl_net_t;
+ type sysfs_t;
+ type unreserved_port_t;
+)
+
+########################################
+#
+# Declarations
+#
+
+type sshportal_t;
+type sshportal_exec_t;
+init_daemon_domain(sshportal_t, sshportal_exec_t)
+
+permissive sshportal_t;
+
+type sshportal_log_t;
+logging_log_file(sshportal_log_t)
+
+type sshportal_var_lib_t;
+files_type(sshportal_var_lib_t)
+
+########################################
+#
+# sshportal local policy
+#
+allow sshportal_t self:capability { setgid setuid };
+allow sshportal_t self:fifo_file rw_fifo_file_perms;
+allow sshportal_t self:unix_stream_socket create_stream_socket_perms;
+allow sshportal_t self:tcp_socket { listen accept };
+allow sshportal_t sysctl_net_t:dir search;
+allow sshportal_t sysctl_net_t:file { open read };
+allow sshportal_t sysfs_t:file { open read };
+allow sshportal_t unreserved_port_t:tcp_socket name_bind;
+allow sshportal_t var_log_t:lnk_file read;
+
+allow init_t sshportal_log_t:file { create open append setattr };
+allow init_t sshportal_log_t:lnk_file read;
+allow init_t sshportal_log_t:dir { reparent rename add_name };
+allow init_t sshportal_t:process2 nnp_transition;
+allow init_t sshportal_var_lib_t:lnk_file read;
+
+manage_dirs_pattern(sshportal_t, sshportal_log_t, sshportal_log_t)
+manage_files_pattern(sshportal_t, sshportal_log_t, sshportal_log_t)
+manage_lnk_files_pattern(sshportal_t, sshportal_log_t, sshportal_log_t)
+logging_log_filetrans(sshportal_t, sshportal_log_t, { dir file lnk_file })
+
+manage_dirs_pattern(sshportal_t, sshportal_var_lib_t, sshportal_var_lib_t)
+manage_files_pattern(sshportal_t, sshportal_var_lib_t, sshportal_var_lib_t)
+manage_lnk_files_pattern(sshportal_t, sshportal_var_lib_t, sshportal_var_lib_t)
+files_var_lib_filetrans(sshportal_t, sshportal_var_lib_t, { dir file lnk_file })
+
+domain_use_interactive_fds(sshportal_t)
+
+files_read_etc_files(sshportal_t)
+
+auth_use_nsswitch(sshportal_t)
+
+miscfiles_read_localization(sshportal_t)
+
+sysnet_dns_name_resolve(sshportal_t)
\ No newline at end of file