MobaXterm x server forwarding with sudo - ssh

I need to execute ikeyman on an IBM HTTP Server. Since I don't want to install a full blown UI on the server, I used MobaXterm with x forwarding for the Windows workstations. When executed as regular user (e.g. /opt/IBM/HTTPServer/bin/ikeyman) it works. For corresponding permissions in certain folders, ikeyman need to run as root:
sudo -i
/opt/IBM/HTTPServer/bin/ikeyman
Exception in thread "main" java.awt.HeadlessException:
No X11 DISPLAY variable was set, but this program performed an operation which requires it.
at java.awt.GraphicsEnvironment.checkHeadless(GraphicsEnvironment.java:217)
at java.awt.Window.<init>(Window.java:547)
at java.awt.Frame.<init>(Frame.java:431)
at java.awt.Frame.<init>(Frame.java:396)
at javax.swing.JFrame.<init>(JFrame.java:200)
at com.ibm.gsk.ikeyman.gui.KeymanFrame.<init>(KeymanFrame.java)
at com.ibm.gsk.ikeyman.gui.KeymanFrame.<init>(KeymanFrame.java)
at com.ibm.gsk.ikeyman.Ikeyman.main(Ikeyman.java)
Not working:
sudo DISPLAY=localhost:10.0 /opt/IBM/HTTPServer/bin/ikeyman (the DISPLAY value was copied from the regular user)
xauth add $(xauth -f /home/user/.Xauthority list | tail -1 )
export DISPLAY=localhost:10.0
/opt/IBM/HTTPServer/bin/ikeyman```

Related

Robot Framework - SSH library - Editing a file on remote server

I am writing a test case in Robot Framework where in, I have to either copy the file from the local machine (windows) to the remote server (linux) or create a new one at the location.
I have used multiple sudo su - command to switch users to root user to reach the desired host. As a result of this, I am not able to use Put File Keyword from SSH Library to upload the file. I have reached at the desired folder location by executing the commands with Write keyword.
Since there is no option left (thats what i realize with my limited knowledge on Robot Framework), i started creating a new file with vi <filename> command. I have also reached the INSERT mode of the file, BUT i am not able to edit text into the file.
Can someone please suggest me how can i either
Copy the file from local windows machine to remote linux server AFTER multiple SU commands (Switch User)
Create a new text file and enter the content.
Please See : the new file which is being created / copied is a certificate file. Hence i do not wish to write the entire content of the certificate in my test suite file
The entire test case looks something like this
First Jump1
Log Starting the connection to AWS VM
# Connection to VM with Public Key
Connection To VM ${hostname} ${username}
Send Command sudo su -
Send Command su - <ServiceUser1>
# Reached the Detination server
Send Command whoami
Send Command ss -tln | grep 127.0.0.1:40
# Connecting to Particular ZIP
Send Command sudo -u <ServiceUser2> /usr/bin/ssh <ServiceUser2>#localhost -p <port>
Send Command sudo su -
# Check Auth Certificate
Send Command mosquitto_pub -h ${mq_host} -p ${mq_port} -u ${mq_username} -P ${mq_password}
In the step Check Auth Certificate, the certificate is checked to be present or not, if present -> delete the current certificate and create the new one (either create a new file or upload from local) and if it not there create a new certificate
though it might not be ideal, but was able to achieve what i wanted to do with
echo "content" > newFilename
echo "update content" >> newFileName

X11 forwarding of a GUI app running in docker

First off: I have read the answers to similar questions on SO, but none of them worked.
IMPORTANT NOTE: The answer below is still valid, but maybe jump to the end for an alternative.
The situation:
App with GUI is running in a docker container (CentOS 7.1) under Arch Linux. (machine A)
Machine A has a monitor connected to it.
I want to access this GUI via X11 forwarding on my Arch Linux client machine. (machine B)
What works:
GUI works locally on machine A (with /tmp/.X11-unix being mounted in the Docker container).
X11 forwarding of any app running outside of docker (X11 forwarding is set up and running properly for non-docker usage).
I can even switch the user while remotely logged in, copy the .Xauthority file to the other user and X11 forwarding works as well.
Some setup info:
Docker networking is 'bridged'.
Container can reach host (firewall is open).
DISPLAY variable is set in container (to host-ip-addr:10.0 because of TCP port 6010 where sshd is listening).
Packets to X forward port (6010) are reaching the host from the container (tcpdump checked).
What does not work:
X11 forwarding of the Docker app
Errors:
X11 connection rejected because of wrong authentication.
xterm: Xt error: Can't open display: host-ip-addr:10.0
Things i tried:
starting client ssh with ssh -Y option on machine B
putting "X11ForwardTrusted yes" in ssh_config on machine B
xhost + (so allow any clients to connect) on machine B
putting Host * in ssh_config on machine B
putting X11UseLocalhost no in sshd_config on machine A (to allow non-localhost clients)
Adding the X auth token in the container with xauth add from the login user on machine A
Just copying over the .Xauthority file from a working user into the container
Making shure .Xauthority file has correct permissions and owner
How can i just disable all the X security stuff and get this working?
Or even better: How can i get it working with security?
Is there at least a way to enable extensive debugging to see where exactly the problem is?
Alternative: The first answer below shows how to effectively resolve this issue. However: I would recommend you to look into a different approach all together, namely VNC. I personally switched to a tigerVNC setup that replaces the X11 forwarding and have not looked back. The performance is just leagues above what X11 forwarding delivered for me. There might be some instances where you cannot use VNC for whatever reason, but i would try it first.
The general setup is now as follows:
-VNC server runs on machine A on the host (not inside a docker container).
-Now you just have to figure out how to get a GUI for inside a docker container (which is a much more trivial undertaking).
-If the docker container was started NOT from the VNC environment, the DISPLAY variable maybe needs ajdusting.
Thanks so much #Lazarus535
I found that for me adding the following to my docker command worked:
--volume="$HOME/.Xauthority:/root/.Xauthority:rw"
I found this trick here
EDIT:
As Lazarus pointed out correctly you also have to set the --net=host option to make this work.
Ok, here is the thing:
1) Log in to remote machine
2) Check which display was set with echo $DISPLAY
3) Run xauth list
4) Copy the line corresponding to your DISPLAY
5) Enter your docker container
6) xauth add <the line you copied>*
7) Set DISPLAY with export DISPLAY=<ip-to-host>:<no-of-display>
*so far so good right?
This was nothing new...however here is the twist:
The line printed by xauth list for the login user looks something like this (in my case):
<hostname-of-machine>/unix:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>
Because i use the bridged docker setup, the X forwarding port is not listening locally, because the sshd is not running in the container. Change the line above to:
<ip-of-host>:<no-of-display> MIT-MAGIC-COOKIE-1 <some number here>
In essence: Remove the /unix part.
<ip-of-host> is the IP address where the sshd is running.
Set the DISPLAY variable as above.
So the error was that the DISPLAY name in the environment variable was not the "same" as the entry in the xauth list / .Xauthority file and the client could therefor not authenticate properly.
I switched back to an untrusted X11 forwarding setting.
The X11UseLocalhost no setting in the sshd_config file however is important, because the incomming connection will come from a "different" machine (the docker container).
This works in any scenario.
Install xhost if you don't have it. Then, in bash,
export DISPLAY=:0.0
xhost +local:docker
After this run your docker run command (or whatever docker command you are running) with -e DISPLAY=$DISPLAY
It works usually via https://stackoverflow.com/a/61060528/429476
But if you are running docker with a different user than the one used for ssh -X into the server with; then copying the Xauthority only helped along with volume mapping the file.
Example - I sshed into the server with alex user.Then ran docker after su -root and got this error
X11 connection rejected because of wrong authentication.
After copying the .XAuthoirty file and mapping it like https://stackoverflow.com/a/51209546/429476 made it work
cp /home/alex/.Xauthority .
docker run -it --network=host --env DISPLAY=$DISPLAY --privileged \
--volume="$HOME/.Xauthority:/root/.Xauthority:rw" \
-v /tmp/.X11-unix:/tmp/.X11-unix --rm <dockerimage>
More details on wiring here https://unix.stackexchange.com/a/604284/121634
Some clarifying remarks. Host is A, local machine is B
Ive edited this post to note things that I think should work in theory but haven't been tested, vs things I know to work
Running docker non-interactively
If your docker is running not interactively and running sshd, you can use jumphosts or proxycommand and specify the x11 client to run. You should NOT volume share your Xauthority file with the container, and sharing -e DISPLAY likely has no effect on future ssh sessions
Since you essentially have two sshd servers, either of the following should work out of the box
if you have openssh-client greater than version 7.3, you can use the following command
ssh -X -J user-on-host#hostmachine,user-on-docker#dockercontainer xeyes
If your openssh client is older, the syntax is instead
(google says the -X is not needed in the proxy command, but I am suspicious)
ssh -X -o ProxyCommand="ssh -W %h:%p user-on-host#hostmachine" user-on-docker#dockermachine xeyes
Or ssh -X into host, then ssh -X into docker.
In either of the above cases, you should NOT share .Xauthority with the container
Running docker interactively from within the ssh session
The easiest way to get this done is to set --net=host and X11UseLocalhost yse.
If your docker is running sshd, you can open a second ssh -X session on your local machine and use the jumphost method as above.
If you start it in the ssh session, you can either -e DISPLAY=$DISPLAY or export it when you're in. You might have to export it if you attach to an exiting container where this line wasn't used.
Use these docker args for --net host and x11uselocalhost yes
ssh -X to host
-e DISPLAY=$DISPLAY
-v $HOME/.Xauthority:/home/same-as-dash-u-user/.Xauthority
-u user
What follows is explanation of how everything works and other approaches to try
About Xauthority
ssh -X/-Y set up a session key in the hosts Xauthority file, and then sets up a listen port on which it places an x11 proxy that uses the session key, and converts it to be compatible with the key on your local machine. By design, the .Xauthority keys will be different between your local machine and the host machine. If you use jumphosts/proxycommand the keys between the host and the container will yet again be different from each other. If you instead use ssh tunnels or direct X11 connection, you will have to share the host Xauthority with the container, in the case of sharing .Xauthority with the container, you can only have one active session per user, since new sessions will invalidate the previous ones by modifying the hosts .Xauthority such that it only works with that session's ssh x11 proxy
X11UserLocalhost no theory##
Even Though X11UseLocalhost no causes the x server to listen on the wildcard address, With --net host I could not redirect the container display to localhost:X.Y where x and why are from the host $DISPLAY
X11UseLocalhost yes is the easy way
If you choose X11UseLocalhost yes the DISPLAY variable on the host becomes localhost:X:Y, which causes the ssh x11 proxy to listen only on localhost port x.
If X11UseLocalhost is no, the DISPLAY variable on the host becomes the host's hostname:X:Y, which causes the xerver to listen on 0.0.0.0:6000+X and causes xclients to reach out over the network to the hostname specified.
this is theoretical, I don't yet have access to docker on a remote host to test this
But this is the easy way. We bypass that by redirecting the DISPLAY variable to always be localhost, and do docker port mapping to move the data from localhost:X+1.Y on the container, to localhost:X.Y on the host, where ssh is waiting to forward x traffic back to the local machine. The +1 makes us agnostic to running either --net=host or --net=bridge
setting up container ports requires specifying expose in the dockerfile and publishing the ports with the -p command.
Setting everything up manually without ssh -X
This works only with --net host. This approach works without xauth because we are directly piping to your unix domain socket on the local machine
ssh to host without -X
ssh -R6010:localhost:6010 user#host
start docker with -e DISPLAY=localhost:10.1 or export inside
in another terminal on local machine
socat -d -d TCP-LISTEN:6010,fork UNIX-CONNECT:/tmp/.X11-unix/X0
In original terminal run xclients
if container is net --bridged and you can't use docker ports, enable sshd on the container and use the jumphosts method

Issue installing virtualmin in vps

Trying to install Virtualmin in my new Ubuntu Xenial vps, executing install.sh, I get the following error:
[... up to here all fine..]
Processing triggers for dovecot-core (1:2.2.22-1ubuntu2.2) ...
Job for dovecot.service failed because the control process exited with error cod e. See "systemctl status dovecot.service" and "journalctl -xe" for details.
invoke-rc.d: initscript dovecot, action "restart" failed.
dpkg: error processing package dovecot-core (--configure):
subprocess installed post-installation script returned error exit status 1
Processing triggers for libapache2-mod-php7.0 (7.0.8-0ubuntu0.16.04.3) ...
Errors were encountered while processing:
dovecot-core
FATAL - Fatal Error Occurred: Something went wrong during installation: 0
FATAL - Cannot continue installation.
FATAL - Attempting to remove virtualmin repository configuration, so the install ation can be
FATAL - re-attempted after any problems have been resolved.
FATAL - Removing temporary directory and files.
FATAL - If you are unsure of what went wrong, you may wish to review the log
FATAL - in /root/virtualmin-install.log
I have installed virtualmin in other vps and did not have such issue before. I meet the same issue in this vps also if I change operating system. What could I do to solve? Thanks
I wanted to install virtualmin on Ubuntu 16.04; I met same issues (as in your log); the error is quite cryptic and unexpected; virtualmin setup worked flawlessly in other vps.
A particular thing of my new vps is that ipv6 is not supported; it is probably the same in your case. Working on this information I made virtualmin work as expected, with the following steps:
fresh install of Ubuntu 16.04
apt-get install dovecot-common dovecot-imapd dovecot-pop3d
(these packages are the part related to dovecot for Ubuntu, taken from virtualmin install.sh). This gave issues.
Then edited: /etc/dovecot/dovecot.conf file.. uncommenting the line "listen = *, ::" and setting it to "listen = *" (listen just to ipv4 instead of also ipv6)
then again "apt-get install dovecot-common dovecot-imapd dovecot-pop3d", to check that installation finely completes.
install virtualmin: "/bin/sh install.sh"
service apache2 restart
In /etc/hosts comment the rows related to ipv6 (those with ::)
remove the "ipv6=1" line from /etc/webmin/miniserv.conf
/etc/init.d/webmin restart (now webmin should be up and working at https://yourip:10000)
I've tried these steps to install VirtualMin on my VPS Ubuntu 16.04. I am damn sure it will work for you.
Here are some prerequisites of the VirtualMin on Ubuntu:
-> You must have a new Ubuntu VPS or system with at 1 GB RAM.
-> You must have root access or access to a user with Sudo privileges.
-> A valid hostname set on your server’s primary IP address.
-> Two registered custom nameservers for Virtualmin.
Steps:
Step 1: Update your system with the latest available version:
Linux command: apt-get update
Step 2: Set Hostname and FQDN:
For Virtualmin to work properly, you need to configure the hostname and FQDN on the server itself by editing the /etc/hostname and /etc/hosts files, as well as update your DNS settings so DNS lookups resolve properly.
Linux command: hostname
To change the hostname for your server, open the file /etc/hostname in your editor:
Linux command: sudo nano /etc/hostname
Delete the current hostname and replace it with your hostname:
Use just the hostname, not the entire FQDN, in this file. For example, if your FQDN is demo.yourdomainname.com, enter demo in this file.
Save the file and exit the editor.
Next, add both the hostname and FQDN in the /etc/hosts file:
Linux command: sudo nano /etc/hosts
Modify the line that starts with 127.0.0.1 to use your FQDN and hostname, in that order:
127.0.1.1 your_hostname.your_domain.com your_hostname
127.0.0.1 localhost
...
Remember to replace your_hostname and your_domain.com with your own hostname and domain name. Save the file and exit the editor.
To check if the name has been changed correctly, reboot your server.
Linux command: sudo reboot
Step 3: Download and install Virtualmin
To install Virtualmin, download and run the official Virtualmin installation script, which will install Virtualmin, and Webmin, along with a LAMP stack, BIND, and Postfix.
Use wget to download the script:
Linux command: wget http://software.virtualmin.com/gpl/scripts/install.sh -O /tmp/virtualmin-install.sh
After the Virtualmin script has been downloaded successfully, we will go for the execution of the script. For that, first we will have to make the script file executable by running the following chmod command:
Linux command: chmod +x /tmp/virtualmin-install.sh
Once the file is made executable, we will go further towards running it using a shell. Enter the following command in the terminal to install Virtualmin through script.
Linux command: sh /tmp/virtualmin-install.sh
The script will give a warning message about existing data and compatible operating systems. Press y to confirm that you want to continue the installation.
The installation process may take a few minutes to complete all the steps as it installs various software packages and components.
Step 4: Configuring Webmin Using The Post-Installation Wizard
To configure Webmin, we'll use its web-based Post-Installation Wizard. Open your web browser and navigate to https://your_server_ip:10000. You can also use your fully-qualified domain name to access the site.
Note: Your browser may show a "Your connection is not secure" or "Your connection is not private" warning since Virtualmin uses a self-signed certificate. This warning is normal. You can ignore it.
Next, we'll need to enter the root username and password which is same as of the Linux system's to get access to the Web-based Control Panel of VirtualMin.
Once you have logged in, you'll see the Introduction screen stating that you are going through the steps to configure Virtualmin. Press Next to continue.
On the Memory use screen, select No for Preload Virtual Libraries, because you don't need to run the Virtual User interface all the time. Select Yes for Run email domain lookup server to enable faster mail processing. Press Next to continue.
On the Virus scanning screen, select No for Run ClamAV server scanner so you'll use less RAM. Press Next to continue.
On the Spam filtering screen, select No for Run SpamAssassin server filter and press Next to continue.
On the Database servers screen, select Yes to Run MySQL database server because MySQL server is widely used and supported by most applications, and no to Run PostgreSQL database server. Press Next to continue.
On the MySQL password screen, enter your desired MySQL root password. It should be different from the root password you used to log in to Webmin.
Select Yes if you’d like to remove the test MySQL database
Select Yes if you’d like to remove the anonymous MySQL user
On the MySQL database size screen, select the RAM option that matches the amount of RAM your server has. For a 1GB server, select Large system (1G) on which MySQL is heavily used. Press Next to continue.
On the Nameserver screen, Enter your primary and secondary nameservers which you configured in the prerequisites. If you haven't set these up, check the Skip check for resolvability box to avoid error message and proceed. Press Next to continue.
On the Password storage mode screen, select Store plain-text passwords if you must support password recovery. Otherwise, choose Only store hashed passwords. Here we have chosen plain-text passwords as an example. Press Next to continue.
you will see the All done screen. Click Next to end.
You may see a message stating that Virtualmin's configuration has not been checked. Click the Re-check and refresh the configuration button to check your Virtualmin configuration. Address any errors that the check reports. This process may take a few minutes to complete.
Congratulations! Your server is now configured.

Does the .ssh file automatically come installed on a linux system by default?

If I tell someone to look in
~/.ssh
Can I assume that that folder will always exist on a nix filesystem? Specifically, is it always there on the standard distros of linux and MacOsx? I'm following the github generate ssh keys tutorial, and it appears to assume that ssh is something included by default. Is that true?
Update: apparently MAC OSX has an ssh server installed by default, but it is not enabled. according to the log by Chris Double,
The Apple Mac OS X operating system has SSH installed by default but the SSH daemon is not enabled. This means you can’t login remotely or do remote copies until you enable it.
To enable it, go to ‘System Preferences’. Under ‘Internet & Networking’ there is a ‘Sharing’ icon. Run that. In the list that appears, check the ‘Remote Login’ option.
This starts the SSH daemon immediately and you can remotely login using your username. The ‘Sharing’ window shows at the bottom the name and IP address to use. You can also find this out using ‘whoami’ and ‘ifconfig’ from the Terminal application.
On OS X, Ubuntu, CentOS and presumably other linux distros the ~/.ssh directory does not exist by default in a user's home directory. On OS X and most linux distros the ssh-client and typically an ssh server are installed by default so that can be a safe assumption.
The absence of the ~/.ssh directory does not mean that the ssh client is not installed or that an ssh server is not installed. It just means that particular user has not created the directory or used the ssh client before. A user can create the directory automatically by successfully sshing to a host which will add the host to the client's ~/.ssh/known_hosts file or by generating a key via ssh-keygen. A user can also create the directory manually via the following commands.
mkdir ~/.ssh
chmod 700 ~/.ssh
To test whether an ssh client and/or server is installed and accessible on the path you can use the which command. Output will indicate whether the command is installed and in the current user's path.
which ssh # ssh client
which sshd # ssh server
I would say no. I guess on 99% of the systems there is an ssh server running but IMHO in most cases you need to install that software on your own.
And even if it is installed, the directories are created on the first usage of ssh for that user.

keep server running on EC2 instance after ssh is terminated

Currently, I have two servers running on an EC2 instance (MongoDB and bottlepy). Everything works when I SSHed to the instance and started those two servers. However, when I closed the SSH session (the instance is still running), I lost those two servers. Is there a way to keep the server running after logging out? I am using Bitvise Tunnelier on Windows 7.
The instance I am using is Ubuntu Server 12.04.3 LTS.
For those landing here from a google search, I would like to add tmux as another option. tmux is widely used for this purpose, and is preinstalled on new Ubuntu EC2 instances.
Managing a single session
Here is a great answer by Hamish Downer given to a similar question over at askubuntu.com:
I would use a terminal multiplexer - screen being the best known, and tmux being a more recent implementation of the idea. I use tmux, and would recommend you do to.
Basically tmux will run a terminal (or set of terminals) on a computer. If you run it on a remote server, you can disconnect from it without the terminal dying. Then when you login in again later you can reconnect, and see all the output you missed.
To start it the first time, just type
tmux
Then, when you want to disconnect, you do Ctrl+B, D (ie press Ctrl+B, then release both keys, and then press d)
When you login again, you can run
tmux attach
and you will reconnect to tmux and see all the output that happened. Note that if you accidentally lose the ssh connection (say your network goes down), tmux will still be running, though it may think it is still attached to a connection. You can tell tmux to detach from the last connection and attach to your new connection by running
tmux attach -d
In fact, you can use the -d option all the time. On servers, I have this in my >.bashrc
alias tt='tmux attach -d'
So when I login I can just type tt and reattach. You can go one step further >if you want and integrate the command into an alias for ssh. I run a mail client >inside tmux on a server, and I have a local alias:
alias maileo='ssh -t mail.example.org tmux attach -d'
This does ssh to the server and runs the command at the end - tmux attach -d The -t option ensures that a terminal is started - if a command is supplied then it is not run in a terminal by default. So now I can run maileo on a local command line and connect to the server, and the tmux session. When I disconnect from tmux, the ssh connection is also killed.
This shows how to use tmux for your specific use case, but tmux can do much more than this. This tmux tutorial will teach you a bit more, and there is plenty more out there.
Managing multiple sessions
This can be useful if you need to run several processes in the background simultaneously. To do this effectively, each session will be given a name.
Start (and connect to) a new named session:
tmux new-session -s session_name
Detach from any session as described above: Ctrl+B, D.
List all active sessions:
tmux list-sessions
Connect to a named session:
tmux attach-session -t session_name
To kill/stop a session, you have two options. One option is to enter the exit command while connected to the session you want to kill. Another option is by using the command:
tmux kill-session -t session_name
If you don't want to run some process as a service (or via an apache module) you can (like I do for using IRC) use gnome-screen Install screen http://hostmar.co/software-small.
screen keeps running on your server even if you close the connection - and thus every process you started within will keep running too.
It would be nice if you provided more info about your environment but assuming it's Ubuntu Linux you can start the services in the background or as daemons.
sudo service mongodb start
nohup python yourbottlepyapp.py &
(Use nohup if you want are in a ssh session and want to prevent it from closing file descriptors)
You can also run your bottle.py app using Apache mod_wsgi. (Running under the apache service) More info here: http://bottlepy.org/docs/dev/deployment.html
Hope this helps.
Addition: (your process still runs after you exit the ssh session)
Take this example time.py
import time
time.sleep(3600)
Then run:
$ python3 time.py &
[1] 3027
$ ps -Af | grep -v grep | grep time.py
ubuntu 3027 2986 0 18:50 pts/3 00:00:00 python3 time.py
$ exit
Then ssh back to the server
$ ps -Af | grep -v grep | grep time.py
ubuntu 3027 1 0 18:50 ? 00:00:00 python3 time.py
Process still running (notice with no tty)
You will want the started services to disconnect from the controlling terminal. I would suggest you use nohup to do that, e.g.
ssh my.server "/bin/sh -c nohup /path/to/service"
you may need to put an & in there (in the quotes) to run it in the background.
As others have commented, if you run proper init scripts to start/stop services (or ubuntu's service command), you should not see this issue.
If on Linux based instances putting the job in the background followed by disown seems to do the job.
$ ./script &
$ disown