ssh fails when is being called within windows service - windows-services

I'm calling cmd file that calls ssh to intercommunicate with Linux machine. I use .NET Process class to accomplish this. But when being called within Windows Service call fails with following error:
C:\test>ssh -o StrictHostKeyChecking=no -i private_linux_key user#host "ls"
0 [main] ssh 9496 fhandler_base::dup: dup(some disk file) failed, handle 0, Win32 error 6
dup() in/out/err failed
Everything works when I start application as Console application.
What may be possible reason of this failure and how to fix this?
EDIT All Windows service has to do - somehow kill predefined daemon on Linux machine
Thanks
EDIT
Similar problem described there: http://www.velocityreviews.com/forums/t714254-executing-commands-from-windows-service.html

Maybe this post will save someones time to struggle similar problem. I've finally found solution that works for me. It is ssh -n key
So instead of
ssh -o StrictHostKeyChecking=no -i private_linux_key user#host "ls"
I've used
ssh -n -o StrictHostKeyChecking=no -i private_linux_key user#host "ls"
It still looks like a magic, but it works!

isn't it a problem of access credentials ?
when running your program as a console applicaiton, you are using the access rights of the currently logged on user. however, a Windows Service executes in a special user account (generally "SYSTEM"), and as such is not granted the same access rights.

Related

Docker Windows how to keep container running without login?

I have Docker installed inside a Virtual Machine with Windows Server 2016.
I have a Linux Container from Python3 with NGINX server using --restart=always param, it runs fine while I am logged in, if I restart the VM, the container is no longer active, and it starts only if I log in.
Also if I logout, the container stops.
How can I make a container run as a service without login and keep it running on logout?
I've got a better answer from HERE
The summary is to build a Task and assign it to Task Scheduler to run on Windows start.
All the scripts should be run on powershell
Logon to the windows server/machine where you want the Docker services to start automatically.
Create a file called startDocker.ps1 at your location of choice and save the following script inside it:
start-service -Name com.docker.service
start C:\'Program Files'\Docker\Docker\'Docker Desktop.exe'
Verify that the location of Docker.exe is correct on your machine otherwise modify it in the script accordingly.
Create a file called registerTask.ps1 and save the following script inside it.
$trigger = New-ScheduledTaskTrigger -AtStartup
$action = New-ScheduledTaskAction -Execute "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" -Argument "-File C:\PowershellScripts\startDocker.ps1"
$settings = New-ScheduledTaskSettingsSet -Compatibility Win8 -AllowStartIfOnBatteries
Register-ScheduledTask -Action $action -Trigger $trigger -TaskName "Start Docker on Start up" -Settings $settings -User "Your user" -Password "Your user password" -RunLevel Highest
This is needed so that this user has access to docker services
try
{
Add-LocalGroupMember -Group docker-users -Member "Your user" -ErrorAction Stop
}
catch [Microsoft.PowerShell.Commands.MemberExistsException] { }
Modify the script: You will have to change a couple of things in the scripts above according to your computer/server.
In the $action line, change the location of startdocker.ps1 script file to where you have placed this file.
In the Register-ScheduledTask line change the account user and password to an account user that needs Docker services to be started at the Windows start-up.
Execute registerTask.ps1
Open Windows Powershell as Administrator and set the current directory to where you have placed registerTask.ps1. For example
cd C:\PewershellScripts\
Next execute this script as follows
.\PowershellScripts\
Since I went through quite a lot of pain in order to make this work, here is a solution that worked for me for running a linux container using docker desktop on a windows 10 VM.
First, read this page to understand a method for running a python script as a windows service.
Then run your container using powershell and give it a name e.g
docker run --name app your_container
In the script you run as a service, e.g the main method of your winservice class, use subprocess.call(['powershell.exe', 'path/to/docker desktop.exe]) to start docker desktop in the service. Then wait for docker to start. I did this by using the docker SDK:
client = docker.from_env()
started = False
while not started:
try:
info = client.info()
started = True
except:
time.sleep(1)
When client has started, run your app with subprocess again
subprocess.call(['powershell.exe', 'docker start -interactive app'])
Finally ssh into your container to keep the service and container alive
subprocess.check_call(['powershell.exe', 'docker exec -ti app /bin/bash'])
Now install the service using python service.py install
Now you need to create a service account on the VM that has local admin rights. Go to Services in windows, and find your service in the list of services. Right click -> properties -> Log On and enter the service account details under "This account". Finally, under general, select automatic(delayed) start and start the service.
Probably not the most 'by the book' method, but it worked for me.
what version of docker did you install exactly / in detail?
The procedure to get docker running on a server is very different than for desktops!
It's purely script based as described in detail in the MS virtualization docs
The executable name of the windows-server docker EE (enterprise) service is by the way indeed dockerd as in linux.

dockerize a CLI that prompts for password

Struggling to get a docker app to both pipe output to a file, and read input. Running the same command in bash works fine.
The command is a CLI I created called envwarden (a simple bash script wrapping around the Bitwarden CLI).
Easiest to show an example:
locally
Running it locally (not inside docker), it works as expected:
$ ./envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /home/user ... prompting for credentials
? Email address: my#email.addr
? Master password: [hidden]
The prompts work fine. I can type in my email (shown), password (hidden), and the output goes to /tmp/secrets.txt just fine.
with docker
With docker, things behave a bit differently.
With docker run -ti (or just docker run -t), there's no prompt at all for email or password...
$ docker run --rm -ti envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
# ... no output ...
With docker run -i, the prompt shows, but anything I type is repeated, and password is shown as well! :-/
$ docker run --rm -i envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /root ... prompting for credentials
? Email address: my#email.address
? Email address: my#email.address
? Master password: [input is hidden] my password
? Master password: [hidden]
docker run, without -t or -i it shows the prompt, but fails to get input
$ docker run --rm envwarden/envwarden envwarden --dotenv >/tmp/secrets.txt
.envwarden file not found in /root ... prompting for credentials
? Email address: unable to login or sync with bitwarden.
Further details
Here's the Dockerfile and docker-entrypoint.sh
Question
How can I get docker to match the same behaviour as running locally? i.e. prompt for password without showing it, and redirect output to stdout.
The behavior you observe is due to the way docker run handles standard streams.
In particular, this is related to moby/moby#725 and PR moby/moby#741:
If you pass no -i nor -t flag to docker run: your terminal is not attached to the standard input of your main program, which thereby behaves as if you had typed empty strings as credentials.
If you only pass the -i flag to docker run, your terminal is attached to your program's stdin, but no pseudo-TTY is allocated, implying you get a not very user-friendly CLI interaction (no hiding feature during password typing, and possible duplication of output lines).
If you pass the -it flags to docker run: a pseudo-TTY is allocated, so the password prompt should work (hiding what you type), but at the same time, the stdout and stderr streams are mixed, so when you append the >/tmp/secrets.txt redirection, you don't actually see the prompt as everything is sent to your /tmp/secrets.txt file!
All in all, to achieve what you want I guess you should stick to the -it option, but rather use a bash redirection "inside" the container (not outside) and also rely on some bind-mount option.
Hence the following proof of concept:
export out="/tmp/secrets.txt" # absolute path to the output file in the host
docker run --rm -it -v "$out:$out" envwarden/envwarden \
/bin/bash -c "envwarden --dotenv >$out"
cat "$out"
(This should work normally, but I did not try it on your particular instance, so comments are welcome.)

Jenkins doesn't invoke psexec command, because "Access is denied"

On our project we want to deploy our .Net application to remote machine. For that purpose we have chosen PsExec tool. The propblem is that the commands that work fine in cmd don't work in Jenkins. They look the similar way in Jenkins
bat '%windir%\\sysnative\\PsExec.exe \\\\ipaddress -u user -p password -accepteula -h cmd /c "command" /q"'
Jenkins prints that Access is denied, although it works well in cmd. Why should I do? How it works differently in Jenkins and cmd? Maybe I'm doing something wrong?
Your Jenkins service must be launched by an admin user. Then you'll have access to these commands.

Simultaneous Docker and VirtualBox

Is there any way with which docker can be executed alongside virtualbox or vmware workstation. As I understand docker installer in Windows requires Hyper-V which needs to be disabled for VirtualBox or Workstation.
Install latest Docker for Windows, and VirtualBox. When asked from DfW about enabling Hyper-V cancel it, VirtualBox doesn't work with it, but you can use docker-machine with VirtualBox driver to run docker containers. I had some errors starting the docker machine in VB so here's full guide.
Go to Command Prompt and issue
docker-machine create -d virtualbox --virtualbox-ui-type "gui" default
You can look the boot2docker booting and docker-machine still don't see the IP. After 5 minutes it will timeout with error
"Error creating machine: Error in driver during machine creation: Too many retries waiting for SSH to be available. Last error: Maximum number of retries (60) exceeded".
Next command is docker-machine stop default.
Download and start Process Explorer, we will try to see the command that gives out error.
Issue docker-machine start default in console while Process Explorer is open. Quickly search for docker-machine process and click on ssh.exe child it spawned.
Then right click it and select properties and copy Command line text (hint HOME, SHIFT+END, CTRL+C).
Mine looked like:
C:\WINDOWS\System32\OpenSSH\ssh.exe -F /dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o ConnectionAttempts=3 -o ConnectTimeout=10 -o ControlMaster=no -o ControlPath=none docker#127.0.0.1 -o IdentitiesOnly=yes -i C:\Users\zvelj\.docker\machine\machines\default\id_rsa -p 55011 "exit 0"
Add the verbose flag -v before "exit 0" so we can see what is the error. In my case it was "WARNING: UNPROTECTED PRIVATE KEY FILE!".
To fix that find that private key, right click, select Properties, in dialog go Security tab, Advanced button, Change owner to you, Disable inheritance (remove all), Add new permission entry for your account with full control.
Now issue docker-machine stop default and docker-machine start default. Then just follow instructions in console.
docker-machine regenerate-certs default
#FOR /f "tokens=*" %i IN ('docker-machine env') DO #%i
To verify run docker-machine ls and look for * in ACTIVE column.
To change it back to headless mode you need to change line in "C:\Users{{YOUR USERNAME}}.docker\machine\machines\default\config.json"
"UIType": "guid", to "UIType": "headless",
You will have to shell variables with
#FOR /f "tokens=*" %i IN ('docker-machine env') DO #%i
to enable docker commands for new consoles. Probably best to create a bash script which does that automatically and offers menu choices for starting/stopping containers
I think that only solution might be to use Docker Toolbox (which uses Virtualbox) instead of Docker for Windows ...
https://github.com/docker/for-win/issues/6
Quote from this issue:
I'm closing this issue. While we understand the background for the request, we currently have no concrete plans to offer other virtualization backends for Docker for Windows for the reasons outlined above. We continue having Toolbox and docker-machine updates for non-Hyper-V users.

How do I ssh into the VM for Minikube?

What is the username/password/keys to ssh into the Minikube VM?
You can use the Minikube binary for this, minikube ssh.
Minikube uses boot2docker as its base image, so the default SSH login to the VM ends up being docker:tcuser1.
I too wanted to login without the Minikube command. I found that it drops the SSH key it generates into ~/.minikube/machines//id_rsa.
My machine was named the default "minikube", and therefore I could do:
ssh -i ~/.minikube/machines/minikube/id_rsa docker#$(minikube ip)
For windows hyper-v the answer was
open "Hyper-V Manager"
right click on the "minikube" VM
user "root"
There was no password.. that got me in.
minikube ssh -v 7
It will show you the output where you can see the full SSH command
/usr/bin/ssh -F /dev/null -o PasswordAuthentication=no -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o LogLevel=quiet -o ConnectionAttempts=3 -o ConnectTimeout=10 -o ControlMaster=no -o ControlPath=none docker#127.0.0.1 -o IdentitiesOnly=yes -i ~/.minikube/machines/minikube/id_rsa -p 56290
All the files mentioned are AuthOptions, which can be configured in the config.json file:
$HOME\.minikube\machines\minikube\config.json
Generally, the SSH user is: docker.
If you want to ssh into your Minikube node/VM, then use SSH keys. You can use a Windows client application like WinSCP to configure the keys for your VM. If the format of keys is not as expected (.ppk), then use another client called PuttyGen to convert the keys into the expected format.
After you're done, log in using WinSCP, and it will enable you to shh into the desired VM using the configured keys.
docker/tcuser is the username/password to access to it , and it's also an straight way.
if you just want to master the control platform, then minikube ssh is a quick way to login.
Getting user and password for minikube in Mac.
cat ~/.minikube/machines/minikube/config.json
Loggin on SSH
ssh -i ~/.minikube/machines/minikube/id_rsa docker#$(minikube ip)
Give User Name as - docker
Give password as tcuser and press enter :
minikube ssh -v 7
works for me. This will get to in the ssh docker minikube
minikube ssh docker#{IP Address}
doesn't work for me.

Resources