标签 SSH 下的文章

由于你的公司标准规定,你可能只能允许部分人访问 Linux 系统。或者你可能只能够允许几个用户组中的用户访问 Linux 系统。那么如何实现这样的要求呢?最好的方法是什么呢?如何使用一个简单的方法去实现呢?

是的,我们会有很多种方法去实现它。但是我们应该使用简单轻松的方法。为了简单轻松的完成目的,我们可以通过对 /etc/ssh/sshd_config 文件做必要的修改来实现。在这篇文章中我们将会向你展示实现要求的详细步骤。

为什么我们要这样做呢?是出于安全的原因。你可以访问这个链接来获取更多关于 openSSH 的使用方法。

什么是 SSH ?

openssh 全称为 OpenBSD Secure Shell。Secure Shell(ssh)是一个自由开源的网络工具,它能让我们在一个不安全的网络中通过使用 Secure Shell(SSH)协议来安全访问远程主机。

它采用了客户端-服务器架构(C/S),拥有用户身份认证、加密、在计算机和隧道之间传输文件等功能。

我们也可以用 telnetrcp 等传统工具来完成,但是这些工具都不安全,因为它们在执行任何动作时都会使用明文来传输密码。

如何在 Linux 中允许用户使用 SSH?

通过以下内容,我们可以为指定的用户或用户列表启用 ssh 访问。如果你想要允许多个用户,那么你可以在添加用户时在同一行中用空格来隔开他们。

为了达到目的只需要将下面的值追加到 /etc/ssh/sshd_config 文件中去。 在这个例子中, 我们将会允许用户 user3 使用 ssh。

# echo "AllowUsers user3" >> /etc/ssh/sshd_config

你可以运行下列命令再次检查是否添加成功。

# cat /etc/ssh/sshd_config | grep -i allowusers
AllowUsers user3

这样就行了, 现在只需要重启 ssh 服务和见证奇迹了。(下面这两条命令效果相同, 请根据你的服务管理方式选择一条执行即可)

# systemctl restart sshd
或
# service restart sshd

接下来很简单,只需打开一个新的终端或者会话尝试用不同的用户身份访问 Linux 系统。是的,这里 user2 用户是不被允许使用 SSH 登录的并且会得到如下所示的错误信息。

# ssh [email protected]
[email protected]'s password: 
Permission denied, please try again.

输出:

Mar 29 02:00:35 CentOS7 sshd[4900]: User user2 from 192.168.1.6 not allowed because not listed in AllowUsers
Mar 29 02:00:35 CentOS7 sshd[4900]: input_userauth_request: invalid user user2 [preauth]
Mar 29 02:00:40 CentOS7 unix_chkpwd[4902]: password check failed for user (user2)
Mar 29 02:00:40 CentOS7 sshd[4900]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6  user=user2
Mar 29 02:00:43 CentOS7 sshd[4900]: Failed password for invalid user user2 from 192.168.1.6 port 42568 ssh2

与此同时用户 user3 被允许登入系统因为他在被允许的用户列表中。

# ssh [email protected]
[email protected]'s password: 
[user3@CentOS7 ~]$

输出:

Mar 29 02:01:13 CentOS7 sshd[4939]: Accepted password for user3 from 192.168.1.6 port 42590 ssh2
Mar 29 02:01:13 CentOS7 sshd[4939]: pam_unix(sshd:session): session opened for user user3 by (uid=0)

如何在 Linux 中阻止用户使用 SSH ?

通过以下内容,我们可以配置指定的用户或用户列表禁用 ssh。如果你想要禁用多个用户,那么你可以在添加用户时在同一行中用空格来隔开他们。

为了达到目的只需要将以下值追加到 /etc/ssh/sshd_config 文件中去。 在这个例子中, 我们将禁用用户 user1 使用 ssh

# echo "DenyUsers user1" >> /etc/ssh/sshd_config

你可以运行下列命令再次检查是否添加成功。

# cat /etc/ssh/sshd_config | grep -i denyusers
DenyUsers user1

这样就行了, 现在只需要重启 ssh 服务和见证奇迹了。

# systemctl restart sshd
活
# service restart sshd

接下来很简单,只需打开一个新的终端或者会话,尝试使用被禁用的用户身份被访问 Linux 系统。是的,这里 user1 用户在禁用名单中。所以,当你尝试登录时,你将会得到如下所示的错误信息。

# ssh [email protected]
[email protected]'s password: 
Permission denied, please try again.

输出:

Mar 29 01:53:42 CentOS7 sshd[4753]: User user1 from 192.168.1.6 not allowed because listed in DenyUsers
Mar 29 01:53:42 CentOS7 sshd[4753]: input_userauth_request: invalid user user1 [preauth]
Mar 29 01:53:46 CentOS7 unix_chkpwd[4755]: password check failed for user (user1)
Mar 29 01:53:46 CentOS7 sshd[4753]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6  user=user1
Mar 29 01:53:48 CentOS7 sshd[4753]: Failed password for invalid user user1 from 192.168.1.6 port 42522 ssh2

如何在 Linux 中允许用户组使用 SSH?

通过以下内容,我们可以允许一个指定的组或多个组使用 ssh

如果你想要允许多个组使用 ssh 那么你在添加用户组时需要在同一行中使用空格来隔开他们。

为了达到目的只需将以下值追加到 /etc/ssh/sshd_config 文件中去。在这个例子中,我们将允许 2g-admin 组使用 ssh。

# echo "AllowGroups 2g-admin" >> /etc/ssh/sshd_config

你可以运行下列命令再次检查是否添加成功。

# cat /etc/ssh/sshd_config | grep -i allowgroups
AllowGroups 2g-admin

运行下列命令查看属于该用户组的用户有哪些。

# getent group 2g-admin
2g-admin:x:1005:user1,user2,user3

这样就行了, 现在只需要重启 ssh 服务和见证奇迹了。

# systemctl restart sshd
或
# service restart sshd

是的, user1 被允许登入系统因为用户 user1 属于 2g-admin 组。

# ssh [email protected]
[email protected]'s password: 
[user1@CentOS7 ~]$

输出:

Mar 29 02:10:21 CentOS7 sshd[5165]: Accepted password for user1 from 192.168.1.6 port 42640 ssh2
Mar 29 02:10:22 CentOS7 sshd[5165]: pam_unix(sshd:session): session opened for user user1 by (uid=0)

是的, user2 被允许登入系统因为用户 user2 同样属于 2g-admin 组。

# ssh [email protected]
[email protected]'s password: 
[user2@CentOS7 ~]$

输出:

Mar 29 02:10:38 CentOS7 sshd[5225]: Accepted password for user2 from 192.168.1.6 port 42642 ssh2
Mar 29 02:10:38 CentOS7 sshd[5225]: pam_unix(sshd:session): session opened for user user2 by (uid=0)

当你尝试使用其他不在被允许的组中的用户去登入系统时, 你将会得到如下所示的错误信息。

# ssh [email protected]
[email protected]'s password: 
Permission denied, please try again.

输出:

Mar 29 02:12:36 CentOS7 sshd[5306]: User ladmin from 192.168.1.6 not allowed because none of user's groups are listed in AllowGroups
Mar 29 02:12:36 CentOS7 sshd[5306]: input_userauth_request: invalid user ladmin [preauth]
Mar 29 02:12:56 CentOS7 unix_chkpwd[5310]: password check failed for user (ladmin)
Mar 29 02:12:56 CentOS7 sshd[5306]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6  user=ladmin
Mar 29 02:12:58 CentOS7 sshd[5306]: Failed password for invalid user ladmin from 192.168.1.6 port 42674 ssh2

如何在 Linux 中阻止用户组使用 SSH?

通过以下内容,我们可以禁用指定的组或多个组使用 ssh

如果你想要禁用多个用户组使用 ssh,那么你需要在添加用户组时在同一行中使用空格来隔开他们。

为了达到目的只需要将下面的值追加到 /etc/ssh/sshd_config 文件中去。

# echo "DenyGroups 2g-admin" >> /etc/ssh/sshd_config

你可以运行下列命令再次检查是否添加成功。

# # cat /etc/ssh/sshd_config | grep -i denygroups
DenyGroups 2g-admin

# getent group 2g-admin
2g-admin:x:1005:user1,user2,user3

这样就行了, 现在只需要重启 ssh 服务和见证奇迹了。

# systemctl restart sshd
或
# service restart sshd

是的 user1 不被允许登入系统,因为他是 2g-admin 用户组中的一员。他属于被禁用 ssh 的组中。

# ssh [email protected]
[email protected]'s password: 
Permission denied, please try again.

输出:

Mar 29 02:17:32 CentOS7 sshd[5400]: User user1 from 192.168.1.6 not allowed because a group is listed in DenyGroups
Mar 29 02:17:32 CentOS7 sshd[5400]: input_userauth_request: invalid user user1 [preauth]
Mar 29 02:17:38 CentOS7 unix_chkpwd[5402]: password check failed for user (user1)
Mar 29 02:17:38 CentOS7 sshd[5400]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=192.168.1.6  user=user1
Mar 29 02:17:41 CentOS7 sshd[5400]: Failed password for invalid user user1 from 192.168.1.6 port 42710 ssh2

除了 2g-admin 用户组之外的用户都可以使用 ssh 登入系统。 例如,ladmin 等用户就允许登入系统。

# ssh [email protected]
[email protected]'s password: 
[ladmin@CentOS7 ~]$

输出:

Mar 29 02:19:13 CentOS7 sshd[5432]: Accepted password for ladmin from 192.168.1.6 port 42716 ssh2
Mar 29 02:19:13 CentOS7 sshd[5432]: pam_unix(sshd:session): session opened for user ladmin by (uid=0)

via: https://www.2daygeek.com/allow-deny-enable-disable-ssh-access-user-group-in-linux/

作者:2daygeek 选题:lujun9972 译者:way-ww 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

常用开源工具的省时快捷方式。

我经常使用 SSH。我发现自己每天都要登录多个服务器和树莓派(与我位于同一房间,并接入互联网)。我有许多设备需要访问,并且获得访问权限的要求也不同,因此,除了使用各种 ssh / scp 命令选项之外,我还必须维护一个包含所有连接详细信息的配置文件。

随着时间的推移,我发现了一些省时的技巧和工具,你可能也会发现它们有用。

SSH 密钥

SSH 密钥是一种在不使用密码的情况下认证 SSH 连接的方法,可以用来加快访问速度或作为一种安全措施(如果你关闭了密码访问权限并确保仅允许授权的密钥)。要创建 SSH 密钥,请运行以下命令:

$ ssh-keygen

这将在 ~/.ssh/ 中创建一个密钥对(公钥和私钥)。将私钥(id_rsa)保留在 PC 上,切勿共享。你可以与其他人共享公钥(id_rsa.pub)或将其放置在其他服务器上。

ssh-copy-id

如果我在家中或公司工作时使用树莓派,则倾向于将 SSH 设置保留为默认设置,因为我不担心内部信任网络上的安全性,并且通常将 SSH 密钥(公钥)复制到树莓派上,以避免每次都使用密码进行身份验证。为此,我使用 ssh-copy-id 命令将其复制到树莓派。这会自动将你的密钥(公钥)添加到树莓派:

$ ssh-copy-id [email protected]

在生产服务器上,我倾向于关闭密码身份验证,仅允许授权的 SSH 密钥登录。

ssh-import-id

另一个类似的工具是 ssh-import-id。你可以使用此方法通过从 GitHub 导入密钥来授予你自己(或其他人)对计算机或服务器的访问权限。例如,我已经在我的 GitHub 帐户中注册了各个 SSH 密钥,因此无需密码即可推送到 GitHub。这些公钥是有效的,因此 ssh-import-id 可以使用它们在我的任何计算机上授权我:

$ ssh-import-id gh:bennuttall

我还可以使用它来授予其他人访问服务器的权限,而无需询问他们的密钥:

$ ssh-import-id gh:waveform80

storm

我还使用了名为 Storm 的工具,该工具可帮助你将 SSH 连接添加到 SSH 配置中,因此你不必记住这些连接细节信息。你可以使用 pip 安装它:

$ sudo pip3 install stormssh

然后,你可以使用以下命令将 SSH 连接信息添加到配置中:

$ storm add pi3 [email protected]

然后,你可以只使用 ssh pi3 来获得访问权限。类似的还有 scp file.txt pi3:sshfs pi pi3:

你还可以使用更多的 SSH 选项,例如端口号:

$ storm add pi3 [email protected]:2000

你可以参考 Storm 的文档轻松列出、搜索和编辑已保存的连接。Storm 实际所做的只是管理 SSH 配置文件 ~/.ssh/config 中的项目。一旦了解了它们是如何存储的,你就可以选择手动编辑它们。配置中的示例连接如下所示:

Host pi3
   user pi
   hostname 192.168.1.20
   port 22

结论

从树莓派到大型的云基础设施,SSH 是系统管理的重要工具。熟悉密钥管理会很方便。你还有其他 SSH 技巧要添加吗?我希望你在评论中分享他们。


via: https://opensource.com/article/20/2/ssh-tools

作者:Ben Nuttall 选题:lujun9972 译者:wxy 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Byobu 能让你在保持会话活跃的情况下维护多个终端窗口,通过 SSH 连接、断开、重连以及共享访问。

Byobu 是基于文本的窗口管理器和终端多路复用器。它类似于 GNU Screen,但更现代、更直观。它还适用于大多数 Linux、BSD 和 Mac 发行版。

Byobu 能让你在保持会话活跃的情况下维护多个终端窗口、通过 SSH(secure shell)连接、断开、重连,甚至让其他人访问。

比如,你 SSH 进入树莓派或服务器,并运行(比如) sudo apt update && sudo apt upgrade,然后你在它运行的时候失去了互联网连接,你的命令会丢失无效。然而,如果你首先启动 byobu 会话,那么它会继续运行,在你重连后,你会发现它仍在继续运行。

 title=

Byobu 名称来自于日语的装饰性多面板屏风,它可作为折叠式隔断,我认为这很合适。

要在 Debian/Raspbian/Ubuntu 上安装 byobu:

sudo apt install byobu

接着启用它:

byobu-enable

现在,请退出 SSH 会话并重新登录,你将会在 byobu 会话中登录。运行类似 sudo apt update 命令并关闭窗口(或输入转义序列(Enter + ~ + .)并重新登录。你将看到更新命令在你离开后还在运行。

很多我不常使用的功能。我通常使用的是:

  • F2 – 新窗口
  • F3/F4 – 在窗口间导航
  • Ctrl+F2 – 垂直拆分窗格
  • Shift+F2 – 水平拆分窗格
  • Shift+左箭头/Shift+右箭头 – 在拆分窗格间导航
  • Shift+F11 – 放大(或缩小)拆分窗格

我们如何使用 byobu

Byobu 对于维护 piwheels(一个用于树莓派的方便的,预编译 Python 包)很好用。我水平拆分了窗格,在上半部分显示了 piwheels 监视器,在下半部分实时显示了 syslog 条目。接着,如果我们想要做其他事情,我们可以切换到另外一个窗口。当我们进行协作分析时,这特别方便,因为当我在 IRC 中聊天时,我可以看到我的同事 Dave 输入了什么(并纠正他的错字)。

我在家庭和办公服务器上启用了 byobu,因此,当我登录到任何一台计算机时,一切都与我离开时一样。它正在运行多个作业、在特定目录中保留一个窗口,以另一个用户身份运行进程等。

 title=

Byobu 对于在树莓派上进行开发也很方便。你可以在桌面上启动它,运行命令,然后 SSH 进入,并连接到该命令运行所在的会话。请注意,启用 byobu 不会更改终端启动器的功能。只需运行 byobu 即可启动它。

本文最初发表在 Ben Nuttall 的 Tooling blog 中,并获许重用。


via: https://opensource.com/article/20/2/byobu-ssh

作者:Ben Nuttall 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

使用一组公钥/私钥对让你不需要密码登录到远程 Linux 系统或使用 ssh 运行命令,这会非常方便,但是设置过程有点复杂。下面是帮助你的方法和脚本。

Linux 系统上设置一个允许你无需密码即可远程登录或运行命令的帐户并不难,但是要使它正常工作,你还需要掌握一些繁琐的细节。在本文,我们将完成整个过程,然后给出一个可以帮助处理琐碎细节的脚本。

设置好之后,如果希望在脚本中运行 ssh 命令,尤其是希望配置自动运行的命令,那么免密访问特别有用。

需要注意的是,你不需要在两个系统上使用相同的用户帐户。实际上,你可以把公用密钥用于系统上的多个帐户或多个系统上的不同帐户。

设置方法如下。

在哪个系统上启动?

首先,你需要从要发出命令的系统上着手。那就是你用来创建 ssh 密钥的系统。你还需要可以访问远程系统上的帐户并在其上运行这些命令。

为了使角色清晰明了,我们将场景中的第一个系统称为 “boss”,因为它将发出要在另一个系统上运行的命令。

因此,命令提示符如下:

boss$

如果你还没有在 boss 系统上为你的帐户设置公钥/私钥对,请使用如下所示的命令创建一个密钥对。注意,你可以在各种加密算法之间进行选择。(一般使用 RSA 或 DSA。)注意,要在不输入密码的情况下访问系统,你需要在下面的对话框中的两个提示符出不输入密码。

如果你已经有一个与此帐户关联的公钥/私钥对,请跳过此步骤。

boss$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/myself/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):            <== 按下回车键即可
Enter same passphrase again:                           <== 按下回车键即可
Your identification has been saved in /home/myself/.ssh/id_rsa.
Your public key has been saved in /home/myself/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:1zz6pZcMjA1av8iyojqo6NVYgTl1+cc+N43kIwGKOUI myself@boss
The key's randomart image is:
+---[RSA 3072]----+
|     . ..        |
|   E+ .. .       |
|  .+ .o + o      |
|   ..+.. .o* .   |
|    ... So+*B o  |
|    +   ...==B . |
| . o .   ....++. |
|o o   . . o..o+  |
|=..o.. ..o  o.   |
+----[SHA256]-----+

上面显示的命令将创建公钥和私钥。其中公钥用于加密,私钥用于解密。因此,这些密钥之间的关系是关键的,私有密钥绝不应该被共享。相反,它应该保存在 boss 系统的 .ssh 文件夹中。

注意,在创建时,你的公钥和私钥将会保存在 .ssh 文件夹中。

下一步是将公钥复制到你希望从 boss 系统免密访问的系统。你可以使用 scp 命令来完成此操作,但此时你仍然需要输入密码。在本例中,该系统称为 “target”。

boss$ scp .ssh/id_rsa.pub myacct@target:/home/myaccount
myacct@target's password:

你需要安装公钥在 target 系统(将运行命令的系统)上。如果你没有 .ssh 目录(例如,你从未在该系统上使用过 ssh),运行这样的命令将为你设置一个目录:

target$ ssh localhost date
target$ ls -la .ssh
total 12
drwx------ 2 myacct myacct 4096 Jan 19 11:48 .
drwxr-xr-x 6 myacct myacct 4096 Jan 19 11:49 ..
-rw-r--r-- 1 myacct myacct  222 Jan 19 11:48 known_hosts

仍然在目标系统上,你需要将从“boss”系统传输的公钥添加到 .ssh/authorized_keys 文件中。如果该文件已经存在,使用下面的命令将把它添加到文件的末尾;如果文件不存在,则创建该文件并添加密钥。

target$ cat id_rsa.pub >> .ssh/authorized_keys

下一步,你需要确保你的 authorized_keys 文件权限为 600。如果还不是,执行命令 chmod 600 .ssh/authorized_keys

target$ ls -l authorized_keys
-rw------- 1 myself myself 569 Jan 19 12:10 authorized_keys

还要检查目标系统上 .ssh 目录的权限是否设置为 700。如果需要,执行 chmod 700 .ssh 命令修改权限。

target$ ls -ld .ssh
drwx------ 2 myacct myacct 4096 Jan 14 15:54 .ssh

此时,你应该能够从 boss 系统远程免密运行命令到目标系统。除非目标系统上的目标用户帐户拥有与你试图连接的用户和主机相同的旧公钥,否则这应该可以工作。如果是这样,你应该删除早期的(并冲突的)条目。

使用脚本

使用脚本可以使某些工作变得更加容易。但是,在下面的示例脚本中,你会遇到的一个烦人的问题是,在配置免密访问权限之前,你必须多次输入目标用户的密码。一种选择是将脚本分为两部分——需要在 boss 系统上运行的命令和需要在 target 系统上运行的命令。

这是“一步到位”版本的脚本:

#!/bin/bash
# NOTE: This script requires that you have the password for the remote acct
#       in order to set up password-free access using your public key

LOC=`hostname`  # the local system from which you want to run commands from
                # wo a password

# get target system and account
echo -n "target system> "
read REM
echo -n "target user> "
read user

# create a key pair if no public key exists
if [ ! -f ~/.ssh/id_rsa.pub ]; then
  ssh-keygen -t rsa
fi

# ensure a .ssh directory exists in the remote account
echo checking for .ssh directory on remote system
ssh $user@$REM "if [ ! -d /home/$user/.ssh ]; then mkdir /home/$user/.ssh; fi"

# share the public key (using local hostname)
echo copying the public key
scp ~/.ssh/id_rsa.pub $user@$REM:/home/$user/$user-$LOC.pub

# put the public key into the proper location
echo adding key to authorized_keys
ssh $user@$REM "cat /home/$user/$user-$LOC.pub >> /home/$user/.ssh/authorized_ke
ys"

# set permissions on authorized_keys and .ssh (might be OK already)
echo setting permissions
ssh $user@$REM "chmod 600 ~/.ssh/authorized_keys"
ssh $user@$REM "chmod 700 ~/.ssh"

# try it out -- should NOT ask for a password
echo testing -- if no password is requested, you are all set
ssh $user@$REM /bin/hostname

脚本已经配置为在你每次必须输入密码时告诉你它正在做什么。交互看起来是这样的:

$ ./rem_login_setup
target system> fruitfly
target user> lola
checking for .ssh directory on remote system
lola@fruitfly's password:
copying the public key
lola@fruitfly's password:
id_rsa.pub                                    100%  567   219.1KB/s   00:00
adding key to authorized_keys
lola@fruitfly's password:
setting permissions
lola@fruitfly's password:
testing -- if no password is requested, you are all set
fruitfly

在上面的场景之后,你就可以像这样登录到 lola 的帐户:

$ ssh lola@fruitfly
[lola@fruitfly ~]$

一旦设置了免密登录,你就可以不需要键入密码从 boss 系统登录到 target 系统,并且运行任意的 ssh 命令。以这种免密的方式运行并不意味着你的帐户不安全。然而,根据 target 系统的性质,保护你在 boss 系统上的密码可能变得更加重要。


via: https://www.networkworld.com/article/3514607/setting-up-passwordless-linux-logins-using-publicprivate-keys.html

作者:Sandra Henry-Stocker 选题:lujun9972 译者:laingke 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

你可能已经熟悉使用 ssh 命令访问远程系统。ssh 命令背后所使用的协议允许终端的输入和输出流经安全通道。但是你知道也可以使用 ssh 来安全地发送和接收其他数据吗?一种方法是使用“ 端口转发 port forwarding ”,它允许你在进行 ssh 会话时安全地连接网络端口。本文向你展示了它是如何工作的。

关于端口

标准 Linux 系统已分配了一组网络端口,范围是 0 - 65535。系统会保留 0 - 1023 的端口以供系统使用。在许多系统中,你不能选择使用这些低端口号。通常有几个端口用于运行特定的服务。你可以在系统的 /etc/services 文件中找到这些定义。

你可以认为网络端口是类似的物理端口或可以连接到电缆的插孔。端口可以连接到系统上的某种服务,类似物理插孔后面的接线。一个例子是 Apache Web 服务器(也称为 httpd)。对于 HTTP 非安全连接,Web 服务器通常要求在主机系统上使用端口 80,对于 HTTPS 安全连接通常要求使用 443。

当你连接到远程系统(例如,使用 Web 浏览器)时,你是将浏览器“连接”到你的主机上的端口。这通常是一个随机的高端口号,例如 54001。你的主机上的端口连接到远程主机上的端口(例如 443)来访问其安全的 Web 服务器。

那么,当你有这么多可用端口时,为什么还要使用端口转发呢?这是 Web 开发人员生活中的几种常见情况。

本地端口转发

想象一下,你正在名为 remote.example.com 的远程系统上进行 Web 开发。通常,你是通过 ssh 进入此系统的,但是它位于防火墙后面,而且该防火墙很少允许其他类型的访问,并且会阻塞大多数其他端口。要尝试你的网络应用,能够使用浏览器访问远程系统会很有帮助。但是,由于使用了讨厌的防火墙,你无法通过在浏览器中输入 URL 的常规方法来访问它。

本地转发使你可以通过 ssh 连接来建立可通过远程系统访问的端口。该端口在系统上显示为本地端口(因而称为“本地转发”)。

假设你的网络应用在 remote.example.com 的 8000 端口上运行。要将那个系统的 8000 端口本地转发到你系统上的 8000 端口,请在开始会话时将 -L 选项与 ssh 结合使用:

$ ssh -L 8000:localhost:8000 remote.example.com

等等,为什么我们使用 localhost 作为转发目标?这是因为从 remote.example.com 的角度来看,你是在要求主机使用其自己的端口 8000。(回想一下,任何主机通常可以通过网络连接 localhost 而连接到自身。)现在那个端口连接到你系统的 8000 端口了。ssh 会话准备就绪后,将其保持打开状态,然后可以在浏览器中键入 http://localhost:8000 来查看你的 Web 应用。现在,系统之间的流量可以通过 ssh 隧道安全地传输!

如果你有敏锐的眼睛,你可能已经注意到了一些东西。如果我们要 remote.example.com 转发到与 localhost 不同的主机名怎么办?如果它可以访问该网络上另一个系统上的端口,那么通常可以同样轻松地转发该端口。例如,假设你想访问也在该远程网络中的 db.example.com 的 MariaDB 或 MySQL 服务。该服务通常在端口 3306 上运行。因此,即使你无法 ssh 到实际的 db.example.com 主机,你也可以使用此命令将其转发:

$ ssh -L 3306:db.example.com:3306 remote.example.com

现在,你可以在 localhost 上运行 MariaDB 命令,而实际上是在使用 db.example.com 主机。

远程端口转发

远程转发让你可以进行相反操作。想象一下,你正在为办公室的朋友设计一个 Web 应用,并想向他们展示你的工作。不过,不幸的是,你在咖啡店里工作,并且由于网络设置,他们无法通过网络连接访问你的笔记本电脑。但是,你同时使用着办公室的 remote.example.com 系统,并且仍然可在这里登录。你的 Web 应用似乎在本地 5000 端口上运行良好。

远程端口转发使你可以通过 ssh 连接从本地系统建立端口的隧道,并使该端口在远程系统上可用。在开始 ssh 会话时,只需使用 -R 选项:

$ ssh -R 6000:localhost:5000 remote.example.com

现在,当在公司防火墙内的朋友打开浏览器时,他们可以进入 http://remote.example.com:6000 查看你的工作。就像在本地端口转发示例中一样,通信通过 ssh 会话安全地进行。

默认情况下,sshd 守护进程运行在设置的主机上,因此只有该主机可以连接它的远程转发端口。假设你的朋友希望能够让其他 example.com 公司主机上的人看到你的工作,而他们不在 remote.example.com 上。你需要让 remote.example.com 主机的所有者将以下选项之一添加到 /etc/ssh/sshd_config 中:

GatewayPorts yes       # 或
GatewayPorts clientspecified

第一个选项意味着 remote.example.com 上的所有网络接口都可以使用远程转发的端口。第二个意味着建立隧道的客户端可以选择地址。默认情况下,此选项设置为 no

使用此选项,你作为 ssh 客户端仍必须指定可以共享你这边转发端口的接口。通过在本地端口之前添加网络地址范围来进行此操作。有几种方法可以做到,包括:

$ ssh -R *:6000:localhost:5000                   # 所有网络
$ ssh -R 0.0.0.0:6000:localhost:5000             # 所有网络
$ ssh -R 192.168.1.15:6000:localhost:5000        # 单个网络
$ ssh -R remote.example.com:6000:localhost:5000  # 单个网络

其他注意事项

请注意,本地和远程系统上的端口号不必相同。实际上,有时你甚至可能无法使用相同的端口。例如,普通用户可能不会在默认设置中转发到系统端口。

另外,可以限制主机上的转发。如果你需要在联网主机上更严格的安全性,那么这你来说可能很重要。 sshd 守护程进程的 PermitOpen 选项控制是否以及哪些端口可用于 TCP 转发。默认设置为 any,这让上面的所有示例都能正常工作。要禁止任何端口转发,请选择 none,或仅允许的特定的“主机:端口”。有关更多信息,请在手册页中搜索 PermitOpen 来配置 sshd 守护进程:

$ man sshd_config

最后,请记住,只有在 ssh 会话处于打开状态时才会端口转发。如果需要长时间保持转发活动,请尝试使用 -N 选项在后台运行会话。确保控制台已锁定,以防止在你离开控制台时其被篡夺。


via: https://fedoramagazine.org/using-ssh-port-forwarding-on-fedora/

作者:Paul W. Frields 选题:lujun9972 译者:geekpi 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

我们有时可能需要在远程机器上运行一些命令。如果只是偶尔进行的操作,要实现这个目的,可以登录到远程系统上直接执行命令。但是每次都这么做的话,就有点烦人了。既然如此,有没有摆脱这种麻烦操作的更佳方案?

是的,你可以从你本地系统上执行这些操作,而不用登录到远程系统上。这有什么好处吗?毫无疑问。这会为你节省很多好时光。

这是怎么实现的?SSH 允许你无需登录到远程计算机就可以在它上面运行命令。

通用语法如下所示:

$ ssh [用户名]@[远程主机名或 IP] [命令或脚本]

1) 如何通过 SSH 在远程 Linux 系统上运行命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行 df 命令

$ ssh [email protected] df -h

 Filesystem               Size  Used Avail Use% Mounted on
 /dev/mapper/centos-root   27G  4.4G   23G  17% /
 devtmpfs                 903M     0  903M   0% /dev
 tmpfs                    920M     0  920M   0% /dev/shm
 tmpfs                    920M  9.3M  910M   2% /run
 tmpfs                    920M     0  920M   0% /sys/fs/cgroup
 /dev/sda1               1014M  179M  836M  18% /boot
 tmpfs                    184M  8.0K  184M   1% /run/user/42
 tmpfs                    184M     0  184M   0% /run/user/1000

2) 如何通过 SSH 在远程 Linux 系统上运行多条命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上一次运行多条命令。

同时在远程 Linux 系统上运行 uptime 命令和 free 命令。

$ ssh [email protected] "uptime && free -m"

 23:05:10 up 10 min,  0 users,  load average: 0.00, 0.03, 0.03

              total       used       free     shared    buffers     cached
 Mem:          1878        432       1445          1        100        134
 -/+ buffers/cache:        197       1680
 Swap:         3071          0       3071

3) 如何通过 SSH 在远程 Linux 系统上运行带 sudo 权限的命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行带有 sudo 权限fdisk 命令。

普通用户不允许执行系统二进制(/usr/sbin/)目录下提供的命令。用户需要 root 权限来运行它。

所以你需要 root 权限,好在 Linux 系统上运行 fdisk 命令which 命令返回给定命令的完整可执行路径。

$ which fdisk
 /usr/sbin/fdisk
$ ssh -t [email protected] "sudo fdisk -l"
 [sudo] password for daygeek:

 Disk /dev/sda: 32.2 GB, 32212254720 bytes, 62914560 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes
 Disk label type: dos
 Disk identifier: 0x000bf685

 Device Boot      Start         End      Blocks   Id  System
 /dev/sda1   *        2048     2099199     1048576   83  Linux
 /dev/sda2         2099200    62914559    30407680   8e  Linux LVM

 Disk /dev/sdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes

 Disk /dev/mapper/centos-root: 29.0 GB, 28982640640 bytes, 56606720 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes

 Disk /dev/mapper/centos-swap: 2147 MB, 2147483648 bytes, 4194304 sectors
 Units = sectors of 1 * 512 = 512 bytes
 Sector size (logical/physical): 512 bytes / 512 bytes
 I/O size (minimum/optimal): 512 bytes / 512 bytes

 Connection to centos7.2daygeek.com closed.

4) 如何通过 SSH 在远程 Linux 系统上运行带 sudo 权限的服务控制命令

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行带有 sudo 权限的服务控制命令。

$ ssh -t [email protected] "sudo systemctl restart httpd"

 [sudo] password for daygeek:
 Connection to centos7.2daygeek.com closed.

5) 如何通过非标准端口 SSH 在远程 Linux 系统上运行命令

下面的例子允许用户通过 ssh 在使用了非标准端口的远程 Linux 机器上运行 hostnamectl 命令

$ ssh -p 2200 [email protected] hostnamectl

    Static hostname: Ubuntu18.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 27f6c2febda84dc881f28fd145077187
            Boot ID: bbeccdf932be41ddb5deae9e5f15183d
     Virtualization: oracle
   Operating System: Ubuntu 18.04.2 LTS
             Kernel: Linux 4.15.0-60-generic
       Architecture: x86-64

6) 如何将远程系统的输出保存到本地系统

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行 top 命令,并将输出保存到本地系统。

$ ssh [email protected] "top -bc | head -n 35" > /tmp/top-output.txt
cat /tmp/top-output.txt

 top - 01:13:11 up 18 min,  1 user,  load average: 0.01, 0.05, 0.10
 Tasks: 168 total,   1 running, 167 sleeping,   0 stopped,   0 zombie
 %Cpu(s):  0.0 us,  6.2 sy,  0.0 ni, 93.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
 KiB Mem :  1882300 total,  1176324 free,   342392 used,   363584 buff/cache
 KiB Swap:  2097148 total,  2097148 free,        0 used.  1348140 avail Mem
 PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND
  4943 daygeek   20   0  162052   2248   1612 R 10.0  0.1   0:00.07 top -bc
     1 root      20   0  128276   6936   4204 S  0.0  0.4   0:03.08 /usr/lib/sy+
     2 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [kthreadd]
     3 root      20   0       0      0      0 S  0.0  0.0   0:00.25 [ksoftirqd/+
     4 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [kworker/0:+
     5 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [kworker/0:+
     7 root      rt   0       0      0      0 S  0.0  0.0   0:00.00 [migration/+
     8 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [rcu_bh]
     9 root      20   0       0      0      0 S  0.0  0.0   0:00.77 [rcu_sched]
    10 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [lru-add-dr+
    11 root      rt   0       0      0      0 S  0.0  0.0   0:00.01 [watchdog/0]
    13 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [kdevtmpfs]
    14 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [netns]
    15 root      20   0       0      0      0 S  0.0  0.0   0:00.00 [khungtaskd]
    16 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [writeback]
    17 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [kintegrity+
    18 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [bioset]
    19 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [bioset]
    20 root       0 -20       0      0      0 S  0.0  0.0   0:00.00 [bioset]

或者你也可以使用以下格式在远程系统上运行多条命令:

$ ssh [email protected] << EOF
hostnamectl
free -m
grep daygeek /etc/passwd
EOF

上面命令的输出如下:

Pseudo-terminal will not be allocated because stdin is not a terminal.
    Static hostname: CentOS7.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 002f47b82af248f5be1d67b67e03514c
            Boot ID: dca9a1ba06374d7d96678f9461752482
     Virtualization: kvm
   Operating System: CentOS Linux 7 (Core)
        CPE OS Name: cpe:/o:centos:centos:7
             Kernel: Linux 3.10.0-957.el7.x86_64
       Architecture: x86-64

               total        used        free      shared  buff/cache   available
 Mem:           1838         335        1146          11         355        1314
 Swap:          2047           0        2047

 daygeek:x:1000:1000:2daygeek:/home/daygeek:/bin/bash

7) 如何在远程系统上运行本地 Bash 脚本

下面的例子允许用户通过 ssh 在远程 Linux 机器上运行本地 bash 脚本 remote-test.sh

创建一个 shell 脚本并执行它。

$ vi /tmp/remote-test.sh

#!/bin/bash
#Name: remote-test.sh
#--------------------
 uptime
 free -m
 df -h
 uname -a
 hostnamectl

上面命令的输出如下:

$ ssh [email protected] 'bash -s' < /tmp/remote-test.sh

  01:17:09 up 22 min,  1 user,  load average: 0.00, 0.02, 0.08

               total        used        free      shared  buff/cache   available
 Mem:           1838         333        1148          11         355        1316
 Swap:          2047           0        2047

 Filesystem               Size  Used Avail Use% Mounted on
 /dev/mapper/centos-root   27G  4.4G   23G  17% /
 devtmpfs                 903M     0  903M   0% /dev
 tmpfs                    920M     0  920M   0% /dev/shm
 tmpfs                    920M  9.3M  910M   2% /run
 tmpfs                    920M     0  920M   0% /sys/fs/cgroup
 /dev/sda1               1014M  179M  836M  18% /boot
 tmpfs                    184M   12K  184M   1% /run/user/42
 tmpfs                    184M     0  184M   0% /run/user/1000

 Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

    Static hostname: CentOS7.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 002f47b82af248f5be1d67b67e03514c
            Boot ID: dca9a1ba06374d7d96678f9461752482
     Virtualization: kvm
   Operating System: CentOS Linux 7 (Core)
        CPE OS Name: cpe:/o:centos:centos:7
             Kernel: Linux 3.10.0-957.el7.x86_64
       Architecture: x86-64

或者也可以使用管道。如果你觉得输出不太好看,再做点修改让它更优雅些。

$ vi /tmp/remote-test-1.sh

#!/bin/bash
#Name: remote-test.sh
 echo "---------System Uptime--------------------------------------------"
 uptime
 echo -e "\n"
 echo "---------Memory Usage---------------------------------------------"
 free -m
 echo -e "\n"
 echo "---------Disk Usage-----------------------------------------------"
 df -h
 echo -e "\n"
 echo "---------Kernel Version-------------------------------------------"
 uname -a
 echo -e "\n"
 echo "---------HostName Info--------------------------------------------"
 hostnamectl
 echo "------------------------------------------------------------------"

上面脚本的输出如下:

$ cat /tmp/remote-test.sh  | ssh [email protected]
 Pseudo-terminal will not be allocated because stdin is not a terminal.
 ---------System Uptime--------------------------------------------
  03:14:09 up  2:19,  1 user,  load average: 0.00, 0.01, 0.05

 ---------Memory Usage---------------------------------------------
               total        used        free      shared  buff/cache   available
 Mem:           1838         376        1063          11         398        1253
 Swap:          2047           0        2047

 ---------Disk Usage-----------------------------------------------
 Filesystem               Size  Used Avail Use% Mounted on
 /dev/mapper/centos-root   27G  4.4G   23G  17% /
 devtmpfs                 903M     0  903M   0% /dev
 tmpfs                    920M     0  920M   0% /dev/shm
 tmpfs                    920M  9.3M  910M   2% /run
 tmpfs                    920M     0  920M   0% /sys/fs/cgroup
 /dev/sda1               1014M  179M  836M  18% /boot
 tmpfs                    184M   12K  184M   1% /run/user/42
 tmpfs                    184M     0  184M   0% /run/user/1000
 tmpfs                    184M     0  184M   0% /run/user/0

 ---------Kernel Version-------------------------------------------
 Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

 ---------HostName Info--------------------------------------------
    Static hostname: CentOS7.2daygeek.com
          Icon name: computer-vm
            Chassis: vm
         Machine ID: 002f47b82af248f5be1d67b67e03514c
            Boot ID: dca9a1ba06374d7d96678f9461752482
     Virtualization: kvm
   Operating System: CentOS Linux 7 (Core)
        CPE OS Name: cpe:/o:centos:centos:7
             Kernel: Linux 3.10.0-957.el7.x86_64
       Architecture: x86-64

8) 如何同时在多个远程系统上运行多条指令

下面的 bash 脚本允许用户同时在多个远程系统上运行多条指令。使用简单的 for 循环实现。

为了实现这个目的,你可以尝试 PSSH 命令ClusterShell 命令DSH 命令

$ vi /tmp/multiple-host.sh

 for host in CentOS7.2daygeek.com CentOS6.2daygeek.com
 do
    ssh daygeek@${host} "uname -a;uptime;date;w"
 done

上面脚本的输出如下:

$ sh multiple-host.sh

 Linux CentOS7.2daygeek.com 3.10.0-957.el7.x86_64 #1 SMP Thu Nov 8 23:39:32 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

  01:33:57 up 39 min,  1 user,  load average: 0.07, 0.06, 0.06

 Wed Sep 25 01:33:57 CDT 2019

  01:33:57 up 39 min,  1 user,  load average: 0.07, 0.06, 0.06
 USER     TTY      FROM             [email protected]   IDLE   JCPU   PCPU WHAT
 daygeek  pts/0    192.168.1.6      01:08   23:25   0.06s  0.06s -bash

 Linux CentOS6.2daygeek.com 2.6.32-754.el6.x86_64 #1 SMP Tue Jun 19 21:26:04 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux

  23:33:58 up 39 min,  0 users,  load average: 0.00, 0.00, 0.00

 Tue Sep 24 23:33:58 MST 2019

  23:33:58 up 39 min,  0 users,  load average: 0.00, 0.00, 0.00
 USER     TTY      FROM             [email protected]   IDLE   JCPU   PCPU WHAT

9) 如何使用 sshpass 命令添加一个密码

如果你觉得每次输入密码很麻烦,我建议你视你的需求选择以下方法中的一项来解决这个问题。

如果你经常进行类似的操作,我建议你设置 免密码认证,因为它是标准且永久的解决方案。

如果你一个月只是执行几次这些任务,我推荐你使用 sshpass 工具。只需要使用 -p 参数选项提供你的密码即可。

$ sshpass -p '在这里输入你的密码' ssh -p 2200 [email protected] ip a

 1: lo:  mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
     link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
     inet 127.0.0.1/8 scope host lo
        valid_lft forever preferred_lft forever
     inet6 ::1/128 scope host
        valid_lft forever preferred_lft forever
 2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
     link/ether 08:00:27:18:90:7f brd ff:ff:ff:ff:ff:ff
     inet 192.168.1.12/24 brd 192.168.1.255 scope global dynamic eth0
        valid_lft 86145sec preferred_lft 86145sec
     inet6 fe80::a00:27ff:fe18:907f/64 scope link tentative dadfailed
        valid_lft forever preferred_lft forever

via: https://www.2daygeek.com/execute-run-linux-commands-remote-system-over-ssh/

作者:Magesh Maruthamuthu 选题:lujun9972 译者:alim0x 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出