如何在Windows上(启动时)运行Ubuntu服务?


22

我想在Windows启动时在Linux子系统(Windows上的Ubuntu上的Bash)上启动SSH服务器。问题是当关闭Bash窗口时,所有Linux进程都会终止。

有没有一种方法可以使Linux进程在没有bash窗口的情况下在后台永久运行?

Answers:


26

通过寻求帮助找到了一个相关的教程:

最初由github用户imjakey,fpqc,qris,therealkenc,Manouchehri和aseering(myself)讨论并整理出来:

https://github.com/Microsoft/BashOnWindows/issues/612

请注意,运行sshd具有安全隐患。在WSL的安全模型需要花费更长的时间之前,您应该假定可以ssh进入Windows框的任何人都有权以运行sshd的Windows用户的身份执行任何命令,而不管Linux级别的权限如何。(权限可能比实际中的限制更严格,但是WSL的初始安全模型并不是很复杂。)

尝试汇总来自github的指令:

  • 通过sudo dpkg-reconfigure openssh-server在bash shell中运行来生成SSH主机密钥
  • 运行sudo nano /etc/ssh/sshd_config; 编辑该UsePrivilegeSeparation yes行以读取 UsePrivilegeSeparation no。(这是必需的,因为 UsePrivilegeSeparation使用了chroot()WSL当前不支持的系统调用。)
  • 仍在编辑时 /etc/ssh/sshd_config,您可以选择更改 PasswordAuthentication noPasswordAuthentication yes。否则,您将必须设置SSH密钥。
  • 保存 /etc/ssh/sshd_config并退出。
  • 运行sudo visudo以编辑sudoers文件。添加行

    $USER ALL = (root) NOPASSWD: /usr/sbin/sshd -D
    

    用您的Linux用户名替换“ $ USER”。保存并退出。如果visudo抱怨您的更改无效,请对其进行修复,直到其报告有效为止;否则,请执行以下操作。否则,您可以在系统上破坏sudo!

  • 在Windows一侧,编辑Windows防火墙(以及您可能正在运行的任何第三方防火墙)以允许端口22上的传入通信。由于这不是一种超级安全的设置,因此我建议仅允许来自家庭的传入流量(专用)和域网络,而不是来自公共Internet。
  • autostartssh.vbs在Windows中创建一个包含以下内容的文本文件 :

    set ws=wscript.createobject("wscript.shell")
    ws.run "C:\Windows\System32\bash.exe -c 'sudo /usr/sbin/sshd -D'",0
    
    • 双击脚本。它应该以sshd开头;您应该可以使用ssh进入Windows计算机。
    • 打开Windows的任务计划程序。添加autostartssh.vbs在系统启动时运行的任务。使用wscript.exe作为运行命令和VBS脚本位置作为参数。

就是这样-您的Windows计算机应该正在运行Linux openssh服务器!


VBS脚本对我没有任何帮助。sshd没有显示在资源监视器的“网络”选项卡中。
megamaiku

我写了一个流程调度程序github.com/131/dispatcher,它可以让您在没有Windows的情况下生成bash。
131

@megamaiku:我有同样的问题。事实证明,由于我没有正确执行“ visudo”部分,运行sshd的小片段被卡在了(不可见的)密码提示中。首先,我在sudoers文件中间的某处添加了NOPASSWD行。一旦我将其移至底部,它就起作用了!
ltjax

1
它目前与一起使用UsePrivilegeSeparation = yes,除了sudo /bin/mkdir -p /var/run/sshd在启动sshd之前还需要运行(创建特权分离目录)。WLS现在是否支持chroot(),openssh源代码中是否存在替代方法,还是= No设置了更多安全建议?此外,Windows任务,似乎只为了我的工作,如果我的用户已登录。
init_js

这非常好。我建议,为了使事情变得简单,请移动SSH正在侦听的端口,例如3322,这是随机的。注释掉/etc/ssh/sshd_config读入的行Port 22并切换到Port 8822。原因之一是Windows在22上运行某种SSH进程。我看到有建议说禁用它没有问题,但是我发现仅切换WSL SSH端口是最容易的。
knickum '18

4

我需要做同样的事情。

这是在Windows启动时使用cron的所有服务启动Ubuntu Linux子系统的方法,并提供了“重新启动” Linux子系统的方法。

我已经在我们的服务器上成功托管了openssh-server,nginx和mariadb数据库。

安装Linux子系统

  • 以管理员身份打开Powershell
  • 糊:

    Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
    
  • 从Windows应用商店安装Ubuntu。

删除sudo密码提示(必填)

  • Open bash(Linux子系统安装此程序)
  • 糊:

    sudo sed -i "s/%sudo.*/%sudo ALL=(ALL:ALL) NOPASSWD:ALL/g" /etc/sudoers
    

启用S​​SH密码登录(可选)

  • 公开重击
  • 糊:

    sudo sed -i '/StrictModes yes/c\StrictModes no' /etc/ssh/sshd_config
    sudo sed -i '/ChallengeResponseAuthentication/c\ChallengeResponseAuthentication no' /etc/ssh/sshd_config
    sudo sed -i '/PasswordAuthentication/c\PasswordAuthentication yes' /etc/ssh/sshd_config
    

Windows启动时自动登录(如果您具有密码或RDP,则必须输入)

  • 打开netplwiz
  • 取消选中“用户必须输入用户名和密码...”
  • 以管理员身份打开regedit
  • 浏览到

    HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon
    
  • 创建一个新字符串DefaultPassword,并将用户的密码写为value。

在启动时运行bash / cron循环

  • 创建一个名为文件linux.batshell:startup
  • 糊:

    C:\Windows\System32\bash.exe -c 'while [ true ]; do sudo /usr/sbin/cron -f; done'
    

将应用程序/服务添加到cron上启动

  • 公开重击
  • sudo crontab -e
  • 选择nano(或您知道如何保存的任何编辑器)
  • 附加启动应用程序,例如openssh-server,nginx,mysql,php:

    PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
    @reboot . $HOME/.profile; /usr/sbin/sshd -D
    #@reboot . $HOME/.profile; service php7.1-fpm start # Uncomment for php7.1 fpm
    #@reboot . $HOME/.profile; service mysql start # Uncomment for mysql/mariadb
    #@reboot . $HOME/.profile; service nginx start # Uncomment for nginx
    
  • 保存并退出:ctrlx,然后按yenter

在不重新启动Windows的情况下重新启动Linux子系统

  • 在以下位置打开bash或SSH

    sudo service ssh restart
    
  • 这将关闭当前实例并创建一个应用cron的新实例。

额外-安装PHP 7.1(不太简单)

  • 运行以下命令以进行标准设置:

    mkdir /run/php && chmod -R 777 /run/php
    sudo add-apt-repository ppa:ondrej/php && sudo apt update
    PHPV=7.1 && sudo apt install --allow-unauthenticated -y php${PHPV}-fpm php${PHPV}-gd php${PHPV}-json php${PHPV}-mysqlnd php${PHPV}-curl php${PHPV}-intl php${PHPV}-mcrypt php${PHPV}-imagick php${PHPV}-zip php${PHPV}-xml php${PHPV}-mbstring
    
  • 运行以下命令以进行“ OwnCloud”设置:

    PHPV=7.1 && apt install --allow-unauthenticated -y php${PHPV}-redis redis-server php${PHPV}-ldap php${PHPV}-smbclient
    

额外-安装Nginx Web服务器

  • 运行以下命令以使用PHP7.1进行基本设置:

    sudo add-apt-repository ppa:nginx/stable
    sudo apt update && sudo apt -y install nginx
    sudo sed -i 's:access_log /var/log/nginx/access.log;:access_log off;:g' /etc/nginx/nginx.conf
    sudo sed -i '/index index.html/c\\tindex index.html index.php index.htm index.nginx-debian.html;' /etc/nginx/sites-available/default
    STR='}\n\n\tlocation ~ \.php$ {\n\t\tinclude snippets\/fastcgi-php.conf;\n\t\tfastcgi_pass unix:\/var\/run\/php\/php7.1-fpm.sock;\n\t}'
    sudo sed -i "0,/}/s//$STR\n/" /etc/nginx/sites-available/default
    sudo service nginx restart
    

额外-安装mariadb的mysql数据库

  • 为mysql数据库服务器运行以下命令:

    RELEASE=`lsb_release -a | tail -1 | cut -f2`
    sudo apt install software-properties-common
    sudo apt-key adv --recv-keys --keyserver hkp://keyserver.ubuntu.com:80 0xF1656F24C74CD1D8
    sudo add-apt-repository "deb [arch=i386,amd64,ppc64el] https://mirrors.evowise.com/mariadb/repo/10.3/ubuntu $RELEASE main"
    sudo apt update && sudo apt --allow-unauthenticated -y install mariadb-server
    
  • 出现提示时,设置根数据库用户密码。


那太聪明了!和精确的指示,谢谢。有没有一种方法可以避免完全跳过“ sudo”密码?
greg

我不建议再使用Linux子系统。应用程序兼容性差,不稳定,工具无法正常运行-bash集成等。使用msys2代替,它为您提供了出色的bash shell,并允许您通过其安装许多应用程序pacman软件包管理器-最重要的是,所有应用程序都是.exe。您需要做的就是将bin目录添加到Windows中的环境变量中。我现在在Windows中使用Linux命令,反之亦然。我所有的Windows脚本都是在bash中完成的。

1

@poma的答案非常好,这也是我答案的基础。我想对其进行一些改进:

  • 使用service而不是sshd直接调用:'sudo service ssh start'代替'sudo /usr/sbin/sshd -D'。这样,即使您多次调用该脚本,也最多只有一个sshd进程。另外,使用另一个运行脚本杀死它很容易'sudo service ssh stop'。在sudoers文件中,只需替换/usr/sbin/sshd -D/usr/sbin/service
  • 如果你在调用设置sshd直接,摆脱的-D选择,因为这将提出一个过程,前景无限。如果您不相信我,只需执行top一下,每次调用该脚本时,您都会看到一个init和一个sudo过程。不要忘记也删除-Dsudoers文件中的选项!
  • 使用PowerShell而不是vbs!创建一个名为的文件,autostartsshd.ps1并粘贴以下内容:bash -c 'sudo service ssh start'。要执行脚本,请右键单击它,然后单击Run with PowerShell

另一个堆栈溢出问题具有类似的步骤:https : //superuser.com/a/1114162/182590

希望能帮助到某人:)


您确定这行得通吗?在前台运行sshd旨在保持ba​​sh会话保持打开状态(多个实例不会有问题,因为重复实例将无法启动)。如果您只运行sudo service ssh start然后关闭bash,它将杀死ssh守护程序。至少在编写指南时就是这样做的。
波马

@Poma随着Windows 10的最新更新,Linux应用程序现在可以在后台运行,因此我认为这应该可以正常工作。
JacobTheDev

1

放入bash -c "echo [password] | service ssh start"Windows启动脚本,并使用您自己的sudo密码替换[password]


您不能仅将密码通过管道发送到sudo提示符(不是您的命令甚至还包括sudo句子所暗示的必要关键字)。这就是行不通的。并不是说您应该始终以纯文本形式存储密码!
adam_0

1

@Poma和@Hintron的答案很好。

我想扩展一下最后一点的描述,即如何在Windows Task Scheduler中添加ssh任务,因为它需要切换一些选项:

  • 运行“任务计划程序”。在左侧列表中,选择“任务计划程序(本地)”,然后转到“操作”菜单和“创建任务”。
  • 常规选项卡:
    • 名称:“ ssh”
    • 选择“运行是否登录用户”
  • 触发器标签:
      • 开始任务:“启动时”
  • 动作标签:
      • 程序/脚本:C:\ Windows \ System32 \ bash.exe
      • 添加参数(可选):-c“ sudo / usr / sbin / service ssh start”
  • 条件:
    • 取消选择“仅当计算机使用交流电源时才启动任务
  • 设定值
    • 取消选择“如果任务运行时间超过

它用于直接bash调用。无需将其包装在vbs或powershell脚本中。

我使用服务命令的原因是@Hintron解释的。此外,直接sshd调用会产生错误

缺少特权分离目录:/ var / run / sshd

在这种情况下,应通过sudo visudo命令将该条目添加

ALL ALL = (root) NOPASSWD: /usr/sbin/service ssh *

还要注意,这里所有用户(第一列)都可以启动或停止sshd。如果您只是该Windows计算机的一个用户,那应该没问题。


1
  1. 创建一个名为的文件wsl_setup.bat并添加内容,如下所示

    wsl -u root -e sudo service ssh start
    wsl -u root -e sudo service nginx start
    
  2. wsl_setup.bat文件添加到Windows启动文件夹Windows-10-change-startup-apps

  3. 重新启动并登录您的Windows帐户(是的,您需要登录)

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.