Last active
October 17, 2024 17:02
-
-
Save samhocevar/00eec26d9e9988d080ac to your computer and use it in GitHub Desktop.
Configure sshd on MSYS2 and run it as a Windows service
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# | |
# msys2-sshd-setup.sh — configure sshd on MSYS2 and run it as a Windows service | |
# | |
# Please report issues and/or improvements to Sam Hocevar <sam@hocevar.net> | |
# | |
# Prerequisites: | |
# — MSYS2 itself: http://sourceforge.net/projects/msys2/ | |
# — admin tools: pacman -S openssh cygrunsrv mingw-w64-x86_64-editrights | |
# | |
# This script is a cleaned up and improved version of the procedure initially | |
# found at https://ghc.haskell.org/trac/ghc/wiki/Building/Windows/SSHD | |
# | |
# Gotchas: | |
# — the log file will be /var/log/msys2_sshd.log | |
# — if you get error “sshd: fatal: seteuid XXX : No such device or address” | |
# in the logs, try “passwd -R” (with admin privileges) | |
# | |
# Changelog: | |
# 27 Jun 2019 — rename service to msys2_sshd to avoid conflicts with Windows OpenSSH | |
# — use mkgroup.exe as suggested in the comments | |
# — fix a problem with CRLF and grep | |
# 24 Aug 2015 — run server with -e to redirect logs to /var/log/sshd.log | |
# | |
set -e | |
# | |
# Configuration | |
# | |
PRIV_USER=sshd_server | |
PRIV_NAME="Privileged user for sshd" | |
UNPRIV_USER=sshd # DO NOT CHANGE; this username is hardcoded in the openssh code | |
UNPRIV_NAME="Privilege separation user for sshd" | |
EMPTY_DIR=/var/empty | |
# | |
# Check installation sanity | |
# | |
if ! /mingw64/bin/editrights -h >/dev/null; then | |
echo "ERROR: Missing 'editrights'. Try: pacman -S mingw-w64-x86_64-editrights." | |
exit 1 | |
fi | |
if ! cygrunsrv -v >/dev/null; then | |
echo "ERROR: Missing 'cygrunsrv'. Try: pacman -S cygrunsrv." | |
exit 1 | |
fi | |
if ! ssh-keygen -A; then | |
echo "ERROR: Missing 'ssh-keygen'. Try: pacman -S openssh." | |
exit 1 | |
fi | |
# | |
# The privileged cyg_server user | |
# | |
# Some random password; this is only needed internally by cygrunsrv and | |
# is limited to 14 characters by Windows (lol) | |
tmp_pass="$(tr -dc 'a-zA-Z0-9' < /dev/urandom | dd count=14 bs=1 2>/dev/null)" | |
# Create user | |
add="$(if ! net user "${PRIV_USER}" >/dev/null; then echo "//add"; fi)" | |
if ! net user "${PRIV_USER}" "${tmp_pass}" ${add} //fullname:"${PRIV_NAME}" \ | |
//homedir:"$(cygpath -w ${EMPTY_DIR})" //yes; then | |
echo "ERROR: Unable to create Windows user ${PRIV_USER}" | |
exit 1 | |
fi | |
# Add user to the Administrators group if necessary | |
admingroup="$(mkgroup -l | awk -F: '{if ($2 == "S-1-5-32-544") print $1;}')" | |
if ! (net localgroup "${admingroup}" | grep -q '^'"${PRIV_USER}"'\>'); then | |
if ! net localgroup "${admingroup}" "${PRIV_USER}" //add; then | |
echo "ERROR: Unable to add user ${PRIV_USER} to group ${admingroup}" | |
exit 1 | |
fi | |
fi | |
# Infinite passwd expiry | |
passwd -e "${PRIV_USER}" | |
# set required privileges | |
for flag in SeAssignPrimaryTokenPrivilege SeCreateTokenPrivilege \ | |
SeTcbPrivilege SeDenyRemoteInteractiveLogonRight SeServiceLogonRight; do | |
if ! /mingw64/bin/editrights -a "${flag}" -u "${PRIV_USER}"; then | |
echo "ERROR: Unable to give ${flag} rights to user ${PRIV_USER}" | |
exit 1 | |
fi | |
done | |
# | |
# The unprivileged sshd user (for privilege separation) | |
# | |
add="$(if ! net user "${UNPRIV_USER}" >/dev/null; then echo "//add"; fi)" | |
if ! net user "${UNPRIV_USER}" ${add} //fullname:"${UNPRIV_NAME}" \ | |
//homedir:"$(cygpath -w ${EMPTY_DIR})" //active:no; then | |
echo "ERROR: Unable to create Windows user ${PRIV_USER}" | |
exit 1 | |
fi | |
# | |
# Add or update /etc/passwd entries | |
# | |
touch /etc/passwd | |
for u in "${PRIV_USER}" "${UNPRIV_USER}"; do | |
sed -i -e '/^'"${u}"':/d' /etc/passwd | |
SED='/^'"${u}"':/s?^\(\([^:]*:\)\{5\}\).*?\1'"${EMPTY_DIR}"':/bin/false?p' | |
mkpasswd -l -u "${u}" | sed -e 's/^[^:]*+//' | sed -ne "${SED}" \ | |
>> /etc/passwd | |
done | |
mkgroup.exe -l > /etc/group | |
# | |
# Finally, register service with cygrunsrv and start it | |
# | |
cygrunsrv -R msys2_sshd || true | |
cygrunsrv -I msys2_sshd -d "MSYS2 sshd" -p \ | |
/usr/bin/sshd.exe -a "-D -e" -y tcpip -u "${PRIV_USER}" -w "${tmp_pass}" | |
# The SSH service should start automatically when Windows is rebooted. You can | |
# manually restart the service by running `net stop msys2_sshd` + `net start msys2_sshd` | |
if ! net start msys2_sshd; then | |
echo "ERROR: Unable to start msys2_sshd service" | |
exit 1 | |
fi |
@wapiti96 The script uses //ADD
to tell the msys2 path handling converter to not treat it as a path and convert it to /ADD
.
Make sure you are not setting the environment variable MSYS2_ARG_CONV_EXCL
or other variables related to path conversion.
if you want to execute a windows app say notepad you are running windows service you have to use a weird hack like this
MSYS2_ARG_CONV_EXCL="*" schtasks /create /sc once /tn "NotepadIn10Sec" /tr "notepad.exe" /st $(date -d @"$((current_time=$(date +%s) +40 ))" +"%H:%M:%S") && ( sleep 50; MSYS2_ARG_CONV_EXCL="*" schtasks /delete /tn "NotepadIn10Sec" /f)
assuming you're logged in as the same user
and in case you're on a firewall:
cygrunsrv -R msys2_autossh ; cygrunsrv -I msys2_autossh -d "MSYS2 autossh" -p "/usr/bin/bash.exe" -a "autossh -M 0 -i /home/myuser/.ssh/id_rsa -o UserKnownHostsFile=/home/myuser/.ssh/known_hosts -R 9090:localhost:22 remoteuser@192.168.59.30 -N" -y msys2_sshd
Anyone have a solution to "passwd: unrecoverable error 8646" in Win10 Pro 1809 64-bit?
MSYS ~ # passwd rcpao New password: Re-enter new password: passwd: unrecoverable error 8646 Try again. New password: Re-enter new password: passwd: unrecoverable error 8646 Try again. New password: Re-enter new password: passwd: unrecoverable error 8646 MSYS ~ #
metoo
@improve100 just use a key instead
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I've tried several different versions of this script including this one, https://www.msys2.org/wiki/Setting-up-SSHd/, and https://github.com/rkitover/windows-alt-sshd-msys2/blob/master/msys2-alt-sshd-setup.sh. All have issues.
When I run this script I get the below error:
"The user name could not be found.
More help is available by typing NET HELPMSG 2221.
The option //ADD is unknown.
The syntax of this command is:
NET USER
[username [password | *] [options]] [/DOMAIN]
username {password | *} /ADD [options] [/DOMAIN]
username [/DELETE] [/DOMAIN]
username [/TIMES:{times | ALL}]
username [/ACTIVE: {YES | NO}]
More help is available by typing NET HELPMSG 3506.
ERROR: Unable to create Windows user "
How do I get around this? I tried jouven's instructions. I ran /usr/bin/mkpasswd | grep using my personal account and copied that line into /etc/passwd. I already have a password on my account, but still tried passwd and it said "You may not change the password for ?. I thought that was fine so I continued on and ran the script and got the error above. Any ideas? Thanks