How to grant enough permission for developer on Bastion Host

Dong Nguyen
4 min readNov 13, 2022


In production environment, the access is private by default, developer usually have not permission to access to the database, search engine, or the running application. In case to debug application, running specific query on database, devops need to provide access for developer to able to access to this resource.

So for each use-case, devops need to grant enough permission. Let go through some use-case.

Use Case 1: Developer need to access to the database.

For this use-case we can provider access to the bastion host and allow user to use ssh port-forwarding only. Let’s do it. Assume you have a virtual machine which has ip and an openssh-server which is listening on port 2222.

First login to this instance.

ssh root@ -p 2222

Create user credential for developer.

$ useradd -m -d /home/alice -s /usr/bin/bash alice

Configure openssh server to allow only port-forwarding

cd /etc/ssh
vi sshd_config

add this block to this file

Match User alice
X11Forwarding no
AllowTcpForwarding yes
PermitTTY no
ForceCommand exit
PubkeyAuthentication yes
PasswordAuthentication no

For this configuration, developer only has permission to use port-forwarding, each time use try to login to this server, the user session will be forced to exit. We only support authenticate using public key instead of password to prevent brute force attack.

Let generate a ssh keypair for this user.

❯ ssh-keygen -t ed25519 -f alice -C "alice-user"                     
Generating public/private ed25519 key pair.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in alice
Your public key has been saved in
The key fingerprint is:
SHA256:xeJwT6biReIIn+2GNXp8pveKbLyfP2R58zT5S99xVGM alice-user
The key's randomart image is:
+--[ED25519 256]--+
| |
| . |
| . o + = E.|
| o = * B . o|
| + * S .. ..|
| B + + o +. |
| o.* oo . + =.|
| +o=... o *|
| .=+++o. .+|

~/Desktop/alice-keys on ☁️ (ap-southeast-1)
❯ ll
total 8.0K
-rw------- 1 dong dong 399 Nov 13 11:44 alice
-rw-r--r-- 1 dong dong 92 Nov 13 11:44

~/Desktop/alice-keys on ☁️ (ap-southeast-1)

Now add alice public key to /home/alice/.ssh/authorized_keys

[root@localhost ~]# mkdir -p /home/alice/.ssh
[root@localhost ~]# vi /home/alice/.ssh/authorized_keys

Now, alice is able to use ssh port-forwarding but login to this vm, if alice try to login and get an PTY session, the session will be terminated.

~/Desktop/alice-keys on ☁️  (ap-southeast-1) 
❯ ssh -i alice alice@ -p 2222
PTY allocation request failed on channel 0
Connection to closed.

Now, let test it. On alice machine run this command

$ ssh -i alice -N -L alice@ -p 2222

Send a request to port 8080

$ curl localhost:8080          
<!DOCTYPE html>
<html lang=en>
<meta charset=utf-8>
<meta name=viewport content="initial-scale=1, minimum-scale=1, width=device-width">
<title>Error 404 (Not Found)!!1</title>
*{margin:0;padding:0}html,code{font:15px/22px arial,sans-serif}html{background:#fff;color:#222;padding:15px}body{margin:7% auto 0;max-width:390px;min-height:180px;padding:30px 0 15px}* > body{background:url(// 100% 5px no-repeat;padding-right:205px}p{margin:11px 0 22px;overflow:hidden}ins{color:#777;text-decoration:none}a img{border:0}@media screen and (max-width:772px){body{background:none;margin-top:0;max-width:none;padding-right:0}}#logo{background:url(// no-repeat;margin-left:-5px}@media only screen and (min-resolution:192dpi){#logo{background:url(// no-repeat 0% 0%/100% 100%;-moz-border-image:url(// 0}}@media only screen and (-webkit-min-device-pixel-ratio:2){#logo{background:url(// no-repeat;-webkit-background-size:100% 100%}}#logo{display:inline-block;height:54px;width:150px}
<a href=//><span id=logo aria-label=Google></span></a>
<p><b>404.</b> <ins>That’s an error.</ins>
<p>The requested URL <code>/</code> was not found on this server. <ins>That’s all we know.</ins>

It works, you can see that we can able to forward port 8080 on local machine to port 80 on host , you can try with Amazon RDS.

[Security Bug Found, please ignore this ] Use Case 2: Developer need to execute some command to interact with the infrastructure.

This use case is very common, some specific examples like

  • Use aws-cli to interact with S3 bucket, copy, move, download, etc…
  • Use kubectl to interact with Kubernetes cluster.

Let go with first example, the developer need to access aws s3 bucket to upload file.

For this use-case, devops have to provide access to the bastion host, installing aws-cli on this machine then provider ssh credential to developer so he can able to login.

What devops guys need to restrict here is only provide permission to run aws-cli for user alice .

The archive this goal, we can create new directory and storing whitelisted binary that alice can run, then update PATH variable for alice

In the SSH configuration section, update alice setting to this.

Match User alice
X11Forwarding no
AllowTcpForwarding yes
PermitTTY yes
PubkeyAuthentication yes
PasswordAuthentication no

Then restarting the sshd .

$ systemctl restart sshd

Next, devops config alice ‘s .bash_profile, binary directoryand PATH variable.

$ cd /home/alice
$ mkdir bin
$ chown -R alice: /home/alice
$ echo "export PATH=/home/alice/bin" > .bash_profile
$ chown root:root .bash_profile
# this chmod allow alice can read but modified this file.
# this prevent alice change the PATH
$ chmod 664 .bash_profile

Now if alice login, he will not able to run any command

❯ ssh -i alice alice@ -p 2222 
Last login: Sun Nov 13 12:26:43 2022 from
[alice@localhost ~]$ uname -a
bash: uname: command not found...
Packages providing this file are:
[alice@localhost ~]$

Next step, devops person need to create symbolic link for aws to /home/alice/bin

[root@localhost ~]# ln -s /usr/local/bin/aws /home/alice/bin/aws
[root@localhost ~]# stat /home/alice/bin/aws
File: /home/alice/bin/aws -> /usr/local/bin/aws
Size: 18 Blocks: 0 IO Block: 4096 symbolic link
Device: fd00h/64768d Inode: 37228668 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Context: unconfined_u:object_r:home_bin_t:s0
Access: 2022-11-13 12:32:06.894444010 +0700
Modify: 2022-11-13 12:32:06.894444010 +0700
Change: 2022-11-13 12:32:06.894444010 +0700
Birth: 2022-11-13 12:32:06.894444010 +0700
[root@localhost ~]#

For now, alice can able to login and executing aws command.

~/Desktop/alice-keys on ☁️  (ap-southeast-1) took 6m58s 
❯ ssh -i alice alice@ -p 2222
Last login: Sun Nov 13 12:26:52 2022 from
[alice@localhost ~]$ aws --version
aws-cli/2.8.12 Python/3.9.11 Linux/5.14.0-183.el9.x86_64 exe/x86_64.centos.9 prompt/off
[alice@localhost ~]$

To provide permission for alice to run other command, you can use symbolic link for other binary.