一、实验环境(rhel7.0版本)
主机环境:rhel7.0
各主机信息
主机名 | IP |
---|---|
server | 172.25.254.1 |
client | 172.25.254.2 |
物理机 | 172.25.254.7 |
二、什么是daemon与服务(service)
系统为了某些功能必须要提供一些服务(不论是系统本身还是网络方面),这个服务就称为service。但是service的提供总是需要程序的执行吧,否则如何执行?所以完成这个service的程序我们就称呼它为daemon。举例来说,完成周期性计划任务服务(service)的程序为crond这个daemon。
你不必区区分什么是daemon与service。事实上,你可以将这两者视为相同的东西。因为完成某个服务需要一个daemon在后台中运行,没有这个damon就不会有service,所以不需要分得太清楚。
在Linux中使用时,通常在服务的名称之后会加上一个d,例如计划任务命令建立的at与cron这两个服务,它的程序名会被取为atd与crond,这个d代表的就是daemon的意思。
1、早期的Sytem V的init管理操作中daemon的主要分类(Optional)
(1)服务的启动、关闭与查看方式
所有的服务启动脚本放置于/etc/init.d目录,基本上都是使用bash shell所写成的脚本程序,需要启动、关闭、重新启动、查看状态时,可以通过如下的方式来处理。
- 启动:/etc/init.d/daemon start
- 关闭:/etc/init.d/daemon stop
- 重新启动:/etc/init.d/daemon restart
- 查看状态:/etc/init.d/daemon status
(2)服务启动的类型
init服务的分类中,根据服务是独立启动或被一个总管程序管理而分为两大类
- 独立启动模式(stand alone):服务独立启动,该服务经常常驻于内存中,提供本机或用户夫人服务操作,反应速度快。
- 超级守护进程(super daemon):由特殊的xinetd或inetd这两个总管程序提供的socket对应或端口对应的管理。当没有用户要求某socket或端口时,所需要服务不会被启动。若有用户要求时,xinetd才会去唤醒相对应的服务程序。当该要求结束时,此服务也会被结束。
(3)服务的依赖性问题
init在管理员自己手动处理这些服务时,是没有办法协助唤醒依赖服务的。
(4)运行级别的分类
init是启动后内核主动调用的,然后init可以根据用户自定义的运行级别来唤醒不同的服务,以进入不同的操作界面。基本上Linux提供7个运行级别,分别是0、1、2、3、4、5、6,比较重要的是:1)单人维护模式、3)纯命令行模式、5)图形界面。而各个运行级别的启动脚本是通过/etc/rc.d/rc[0-6]/SXXdaemon链接到/etc/init.d/daemon,链接文件名(SXXdaemon)的功能为:S为启动该服务,XX是数字,为启动顺序。由于SXX的设置,因此在启动时可以【依序执行】所有需要的服务,同时也能解决依赖服务的问题,这点与管理员自己手动处理不太一样。
(5)制定运行级别默认要启动的服务
- 默认要启动:chkconfig daemon on
- 默认不启动:chkconfig daemon off
- 查看默认为启动与否:chkconfig --list daemon
(6)运行级别的切换操作
当你要从命令行界面(runlevel 3)切换到图形界面(runlevel 5),不需要手动启动、关闭该运行级别的相关服务,只要【init 5】即可切换,init会主动去分析/etc/rc.d/rc[35].d/这两个目录内的脚本,然后启动转换运行级别中需要的服务,就完成整体的运行级别切换。
注意:
虽然CentOS 7已经不使用init来管理服务了,不过因为考虑到某些脚本没有办法直接使用systemd处理,因此这些脚本还是被保留下来。
2、systemd使用的unit分类
从Centos 7.x以后,Red Hat系列的发行版放弃沿用多年的System V开机启动服务的流程,就是init启动脚本的方法,改用systemd这个启动服务管理机制。那么,systemd有什么好处呢?好处介绍如下:
(1)并行处理所有服务,加速开机流程
旧有的init启动脚本是【一项一项任务依序启动】的模式,因此不依赖的服务也得要一个一个的等待;
systemd就是可以让所有的服务同时启动,因此你会发现,操作系统启动的速度变快了。
(2)一经要求就响应的on—demand启动方式
systemd全部就是仅有一个systemd服务搭配systemctl命令来处理,无需其他额外的命令来支持。不像System V还要init、chkconfig、service等命令。此外,systemd由于常驻内存,因此任何要求(on—demand)都可以立即处理后续的daemon启动任务。
(3)服务依赖性的自我检查
由于systemd可以自定义服务依赖性的检查,因此如果B服务是架构在A服务上面启动的,当你在没有启动A服务的情况下仅手动启动B服务时,systemd会自动帮你启动A服务。这样就可以免去管理员要一项一项服务去分析的麻烦。
(4)依daemon功能分类
旧的init仅可分为stand alone与super daemon,实在不够好,systemd将服务单位(unit)区分为service、socket、target、path、snapshot、timer等多种不同的类型
(5)将多个daemons集合成为一个群组
如同System V的init里面有个运行级别的特色,systemd亦将许多功能集合成为一个所谓的target项目,这个项目主要在设计操作环境的创建,所以是集合了许多的daemons,亦即是执行某个target就是执行好多个daemon的意思。
(6)向下兼容旧有的init服务脚本
基本上,systemd可以兼容init的启动脚本,因此,旧的init启动脚本也能够通过systemd来管理,只是更高级的systemd功能就没办法支持。
不过,systemd也是有些地方无法完全替换init的,包括:
- 在运行级别的对应上,大概仅有runlevel 1、3、5有对应到systemd的某些target类型而已,没有全部对应。
- 全部的systemd都用systemctl这个管理程序进行管理,而systemctl支持的语法有限制,不像/etc/init.d/daemon就是纯脚本可以自定义参数,systemctl不可自定义参数。
- 如果某个服务启动是管理员自己手动执行启动,而不是使用systemctl去启动(例如你自己手动输入crond以启动crond服务),那么systemd将无法检测到该服务,而无法进一步管理。
- systemd启动过程中,无法与管理员通过标准输入传入信息。因此,自行编写systemd的启动设置时,务必要取消交互机制。(连通过启动时传进的标准输入信息也要避免)
3、systemd的配置文件放置目录
基本上,systemd将过去所谓的daemon执行脚本通通称为一个服务单位(unit),而每种服务单位根据功能来区分时,就分为不同的类型。基本的类型包括
- 系统服务;
- 数据监听与交换socket文件服务(socket);
- 存储系统状态的快照类型
- 提供不同类似运行级别分类的操作环境(target)等。
systemd的配置文件都放置在下面的目录中:
- /usr/lib/systemd/system:每个服务最主要的启动脚本设置,有点类似以前的/etc/init.d下面的文件
- /run/systemd/system:系统执行过程中所产生的服务脚本,这些脚本的优先级要比/usr/lib/systemd/system高
- /etc/systemd/system:管理员根据主机系统的需求所建立的执行脚本,其实这个目录有点像以前/etc/rc.d/rc5.d/Sxx之类的功能,执行优先级又比/run/systemd/system高。
也就是说,到底操作系统启动会不会执行某些服务其实是看/etc/systemd/system下面的设置,所以该目录下面是一堆链接文件。而实际执行的是systemd的启动脚本配置文件,其实都是放置在/usr/lib/systemd/system下面,因此如果你想要修改某个服务启动的设置,应该要去/usr/lib/systemd/system下面才对,/etc/systemd/system仅是链接到正确的执行脚本配置文件而已。所以想要看执行脚本设置,应该要到/usr/lib/systemd/system下面去查看才对。
4、systemd的unit类型分类说明
我们知道vsftpd与crond其实算是系统服务(service),而multi-user要算是执行环境相关的类型(target type),根据这些扩展名的类型,我们大概可以找到如下几种常见的systemd的服务类型。
扩展名 | 主要服务功能 |
.service | 一般服务类型:主要是系统服务,包括服务器本身所需要的本地服务以及网络服务等,经常被使用到的服务大多是这种类型。 |
.socket | 内步程序数据交换的socket服务,主要是IPC的传输信息sockert文件功能。这种类型的服务通常在监控信息传递的socket文件中,当通过此socket文件传递信息要链接服务时,就根据当时的状态将该用户的要求传递到对应的daemon,若daemon尚未启动,则启动该daemon后再传送用户的需求。 使用socket类型的服务一般较少用到,因此在开机启动时通常会稍微延迟启动的时间(因为没有这么常用嘛)。一般本地服务比较多,例如我们的图形界面很多的软件都是通过socket来进行本机程序数据交换的操作。 |
.target | 执行环境类型:其实是一群init的集合,例如上面谈到的multi-user.target其实就是一堆服务的集合,也就是说,选择执行multi-user.target就是执行一堆其他.service或(及).socket之类的服务 |
.mount .automount | 文件系统挂载相关的服务 |
.path | 检测特定文件或目录类型:某些服务需要检测特定的目录来提供队列服务,例如最擦痕嗯件的打印服务,就是通过检测打印队列目录来启动打印功能,这时就得要.path的服务类型支持 |
.timer | 循环执行的服务:这个服务有点类其anacrontab,不过是由systemd主动提供,比auacrontab更加有弹性。 |
三、通过systemctl管理服务
1、什么是服务?服务开启对本机无意义,对客户有意义
2、用什么控制服务?系统初始化进程可以对服务进行相应的控制
3、当前系统初始化进程是什么?systemd(通过pstree命令查看)4、注意:当把sshd的进程杀掉之后,重新systemctl start sshd服务时,进程号pid会发生变化;
systemcytl restart sshd—进程号pid会发生变化;
systemctl reload sshd——进程号pid不会发生变化;
当别人已经通过ssh连接之后,如果利用命令systemctl stop ssd之后,别人不会退出来。只有当关掉系统之后,别人才能退出来。
1、通过systemctl管理单一服务(service unit)的启动/开机启动与查看状态
systemctl [command] [unit]
command主要有:
start:立刻启动后面接的unit。
stop:立刻关闭后面接的unit。
restart:立刻重新启动后面接的unit,亦即执行stop再start的意思
reload:不关闭后面接的unit的情况下,重新加载配置文件,让设置生效
enable:设置下次开机时,后面接的unit会被启动
disable:设置下次开机时,后面接的unit不会被启动
status:目前后面接的这个unit的状态,会列出有没有正在执行,开机默认执行与否、登录等信息等
is-active:目前有没有正在运行中
is-enabled:开机时有没有默认要启用这个unit
(1)systemctl相关命令范例
【1】、范例一:看看目前sshd这个服务的状态是什么
重点在第二、三行,
- Loaded:这行在说明,开机的时候这个unit会不会启动,enabled为开机启动,disabled为开机不会启动。
- Active:现在这个unit的状态是正在执行(running)或没有执行(dead)。
后面几行则是说明这个unit程序的PID状态以及最后几行显示这个服务的日志文件信息。
- 日志文件信息格式为:【时间】 【信息发送主机】 【哪一个服务的信息】 【实际信息内容】
所以上面的显示信息是:这个sshd服务默认开机就启动,而且现在正在运行的意思。
【2】、范例二:正常关闭sshd这个服务
上面的范例中,我们已经关闭了sshd,这样做才是对的。不应该使用kill的方式来关闭一个正常的服务。否则systemctl会无法继续监控该服务,那就麻烦了。
【3】、范例三:正常启动sshd这个服务
【4】、范例四:设置sshd服务开机不自启
看得很清楚,其实就是从/etc/systemd/system下面删除了一个链接文件而已
【5】、范例五:设置sshd服务开机自启
看得很清楚,其实建立了一个链接文件而已
【6】、范例六:查看sshd服务是否已经启动
【7】、范例七:查看sshd服务是否开机自启
(2)Active的daemon目前状态与默认状态
好,再回到systemctl status sshd.service的第3行,不是由各Active的daemon现在状态吗?除了running跟dead之外,有没有其他的状态?有的,基本上有如下常见的状态。
- ative(runing):正有一个或多个进程正在系统中运行的意思。
- active(exited):仅执行一次就正常结束的服务,目前并没有任何进程在系统中执行。
- active(waiting):正在运行当中,不过还需等待其他的事件发生才能继续运行。举例来说,打印的队列相关服务就是这种状态。虽然正在启动中,不过,也需要真的有队列近来(打印工作)这样它才会继续唤醒打印及服务进行下一步的打印功能。
- inactive:这个服务目前没有运行的意思
既然daemon目前的状态就有这么多种,那么daemon的默认状态有没有可能除了disable/enable之外,还有其他的情况?当然有。
- enabled:这个daemon将在开机时被运行
- disabled:这个daemon将在开机时不会被运行
- static:这个daemon不可以自己启动(不可enable),不过可能会被其他的enabled的服务来唤醒(依赖属性的服务)。
- mask:这个daemon无论如何都无法被启动,因为已经被强制注销(非删除)。可以通过systemctl umask方式改回默认状态。
(3)强迫服务注销(mask)的练习
很多服务彼此之间是有依赖性的,比如与网络打印机有关的服务(cpus.socket、cpus.path、cpus.service),目前,cpus.service服务和cpus.path服务的状态是关闭并且是开机不自启动的,而cpus.socket服务的状态的开启的并且是开机不自启动的。当我们打印东西时,却发现cpus.service这个服务竟然启动了。这就是服务之间的依赖性。
cpus是一种打印服务,这个打印服务会启用631端口来提供网络打印机的功能。但是其实我们无需一直启动631端口吧?因此,多了一个名为cpus.socket的服务,这个服务可以在【用户有需要打印时,才会主动唤醒cpus.service】的意思。因此,如果你仅有disable/stop cous.service而忘记了其他两个服务的话,那么当用户向其他两个cpus.path、cpus.socket提出要求时,cpus.service就会被唤醒,所以,你关闭也没用。
比较正规的做法是,要关闭cpus.service是,连同其他两个会唤醒service的cpus.socket与cpus.path通通关闭,就没事了。不正规的做法就是强制注销cous.service,通过mask的方式来将这个服务注销。
【1】、范例一:注销firewalld服务
上面的范例,我们仔细推敲一下,原来整个启动的脚本配置文件被链接到了/dev/null这个空设备,因此,无论如何你是再也无法启动firewalld服务了,通过这个mask功能,就可以不必管其他依赖服务可能会启动这个想要关闭的服务了。虽然是非正规,不过很有效。
【2】范例二:取消注销firewalld服务
2、通过systemctl查看系统上所有的服务
systemctl [command] [--type=TYPE] [--all]
command:
list-units:依据unit显示目前有启动的unit,若加上--all才会列出没启动的。
list-unit=files:依据/usr/lib/system/内的文件,将所有文件列表说明
--type=TYPE:就是unit的类型,主要有service、socket、target、mount、automount、path、timer
【1】、范例一:列出系统上面启动的unit
上图中,列出的项目中,主要的意义是:
- UNIT:项目的名称,包括各unit的类别(看副文件名)。
- LOAD:开机时是否会被加载,默认systemctl显示的是有加载的项目而已。
- ACTIVE:目前的状态,须与后续的SUB搭配,就是我们用systemctl status查看时,active的项目
- DESCRIPTION:详细描述
例外,systemctl都不加参数,其实默认就是list-units的意思。
【2】、范例二:列出所有已经安装的unit有哪些
使用systemctl list-unit-files会将系统上所有的服务通通显示出来,而不像list-units仅以unit分类做答之的说明。至于STATE状态就是前面提到的开机是否会加载的那个状态项目。主要有enabled、disabled、static、mask等。
【3】、列出系统上面service这种类别的daemon
3、通过systemctl管理不同的操作环境(target unit)
(1)列出系统上面与操作系统有关的target项目
上面列出的target项目有很多,但是与操作界面相关性比较高的target主要有下面几个。
- graphical.target:就是命令加上图形界面,这个项目已经包含下面的multi-user.target
- multi-user.target:纯命令行模式
- rescue.target:在无法使用root登陆的情况下,systemd在启动时会多加一个额外的临时系统,与你原本的系统无关,这时你可以取得root的权限来维护你的系统。但是这是额外的系统,因此可能需要用到chroot的方式来取得你原有的系统。
- emergemcy.target:紧急处理系统的错误,还是需要使用root登陆的情况,在无法使用rescue.target时,可以尝试使用这种模式
- shutdown.target:就是关机的模式
- getty.target:可设置你需要几个tty之类的操作,如果你想要降低tty的数量,可以修改它的配置文件
(2)通过systemctl管理不同的操作环境(target unit)
systemctl [command] [unit.target]
command:
get-default:取得目前的target
set-default:设置后面接的target成为默认的操作模式
isolate:切换到后面接的模式
【1】、范例一:我们的测试机器默认是图形界面,先查看是否真为图形界面,再将默认模式转为命令模式
【2】、在不重新启动的情况下,将目前的操作系统改为纯命令行模式,关闭图形界面
该命令同命令“init 3”
【3】、若需要取得图形界面
该命令同命令“init 5”
(3)需要注意的地方
要注意,改变graphical.target以及multi-user.target是通过isolate来完成的。对于刚刚接触systemd的人来讲,可能会这样想,会以为关闭图形界面即可回到multi-user.target。但是使用systemctl stop graphical.target却没有任何回应。这是因为这样想本身就是错的,在service部分用start、stop、restart等参数,在target项目则请使用isolate(隔离不同的操作模式)才对。
(4)systemd提供的切换操作模式的简单命令
systemctl poweroff 系统关机
systemctl reboot 重新开机
systemctl suspend 进入挂起模式
systemctl hibernate 进入休眠模式
systemctl rescue 强制进入恢复模式
systemctl emergency 强制进入紧急模式
什么是暂停与休眠模式?
- suspend:挂起(暂停)模式会将系统的状态数据保存到内存中,然后关闭大部分的系统硬件,当然,并没有实际关机。当用户按下唤醒机器的按钮,系统数据会从内存中恢复,然后重新驱动被大部分关闭的硬件,就开始正常运行,唤醒的速度较快
- hibernate:休眠模式则是将系统状态保存到硬盘当中,保存完毕之后,将计算机关机。当用户尝试唤醒系统时,系统会开始正常运行,然后将保存在硬盘中的系统状态恢复回来。因为数据是由硬盘读出,因此唤醒的性能与你的硬盘速度有关。
4、通过systemctl分析各服务之间的依赖性
我们在上一小节说到graphical.target包含multi-user.target,那这是为什么呢?graphical.target下面还有哪些东西,下面我们就来谈一谈。
systemctl list-dependencies [unit] [--reverse]
选项与参数:
--reverse:反向追踪谁使用这个unit的意思
【1】、范例一:列出目前的target环境下,用到了哪些unit
因为默认的操作模式是multi-user.target,因此这边使用list-dependencies时,所列出的default.target其实就是multi-user.target的内容
【2】、范例二:列出谁用到了multi-user.target服务
【3】、范例三:列出granphical.target服务用到了哪些unit
5、查看socket文件放置的位置
我们知道systemd里面很多的本机会用到的socket服务,里面可能会产生很多的socket文件,那你怎么知道这些socket文件放置在哪里?很简单,还是通过systemctl来管理
6、与systemd的daemon运行过程相关的目录简介
- /usr/lib/systemd/system:使用CentOS官方提供的软件安装后,默认的启动脚本配置文件都放在这里。有点类似以前的/etc/init.d下面的文件,这里的数据尽量不要修改,要修该时,请到/etc/systemd/system下面修改比较好。
- /run/systemd/system:系统执行过程中所产生的服务脚本,这些脚本的优先级要比/usr/lib/systemd/system高
- /etc/systemd/system:管理员根据主机系统的需求所建立的执行脚本,其实这个目录有点像以前/etc/rc.d/rc5.d/Sxx之类的功能,执行优先级又比/run/systemd/system高。
- /etc/sysconfig/*:几乎所有服务都护将初始化的一些选项设置写入到这个目录,网络的设置就卸载/etc/sysconfig/network-scripts这个目录内。
- /var/lib:一些会产生数据的服务都会将它的数据写入到/var/lib目录中。举例来说,数据库管理系统MariaDB的数据库默认写入/var/lib/mysql这个目录。
- /run:放置了好多daemon的缓存,包括locak文件以及PID文件等。
7、网络服务与端口对应简介
大家都说IP就是代表你的主机在因特网上面的【门牌号码】。但是你的主机总是可以提供非常多的网络服务而不止一项功能而已,但我们仅有一个IP。当客户端连接我们的主机时,我们主机是如何辨别不同的服务请求的呢?那就是通过端口号来实现的。
为了统一整个因特网的端口对应服务的功能,好让所有的主机都能够使用相同的机制来提供服务与要求服务,所以就有了“通信协议”。也就是说有些约定俗成的服务都放置在同一端口上面。举例来说,网址中的http会让浏览器向WWW服务器的80端口进行连接的请求。而WWW服务器也会将httpd这个软件监听80端口,这样两者才能够完成连接。
操作系统上面有没有什么设置可以让服务为与端口对应在一起?那就是/etc/services。
[root@server ~]# cat /etc/services
...
ftp 21/tcp
ftp 21/udp fsp fspd
ssh 22/tcp # The Secure Shell (SSH) Protocol
ssh 22/udp # The Secure Shell (SSH) Protocol
...
#这个文件的内容是以下面的格式来显示的。
<daemon name> <port/封包协议> <该服务的说明>
虽然有的时候你可以借由/etc/services来更改一个服务的端口号,不过不建议如此做,因为很有可能会造成一些协议出现错误的情况。
8、什么是网络服务及网络服务是由谁管理的
什么是网络服务?
- 基本上,会产生一个网络监听端口(port)的进程,你就可以称它是网络服务。
网络服务是由谁管理的?
- 网络服务是由SELinux管理的。
四、systemctl针对service类型的配置文件
1、systemctl配置文件相关目录简介
systemd的配置文件大部分放置于/usr/lib/systemd/system目录中。但是Red Hat官方文件指出,该目录主要是原本软件所提供的设置,建议不要修改,而要自ugai的位置应该放置于/etc/systemd/system目录中。举例来说,如果你想要额外修改vsftpd.service的话,它们建议要放置到哪些地方呢?
- /usr/lib/systemd/system/vsftpd.service:官方发布的默认配置文件
- /etc/systemd/system/vsftpd.service.d/custom.conf:在/etc/systemd/system下面建立与配置文件相同文件名的目录,但是要加上.d的扩展名,然后在该目录下建立配置文件即可。另外,配置文件的扩展名最好使用.conf。在这个目录下的文件会【累加其他设置】到/usr/lib/systemd/system/vsftpd.service中
- /etc/systemd/system/vfstpd.service.wants/*:此目录内的文件为链接文件,设置依赖服务的链接,意思是启动vsftpd.service之后,最好再加上该目录下面建议的服务
- /etc/systemd/system/vfstpd.service.requires/*:此目录内的文件为链接文件,设置依赖服务的链接,意思是启动vsftpd.service之前,需要事先启动哪些服务的意思。
2、systemctl配置文件的设置项目简介
下面,我们来看看sshd.service这个配置文件的内容
[root@server ~]# cat /usr/lib/systemd/system/sshd.service [Unit] #这个项目与此unit的解释、执行服务依赖性有关 Description=OpenSSH server daemon After=syslog.target network.target auditd.service [Service] #这个项目与实际执行的命令参数有关 EnvironmentFile=/etc/sysconfig/sshd ExecStartPre=/usr/sbin/sshd-keygen ExecStart=/usr/sbin/sshd -D $OPTIONS ExecReload=/bin/kill -HUP $MAINPID KillMode=process Restart=on-failure RestartSec=42s [Install] #这个项目说明此unit要挂载到哪个target下面 WantedBy=multi-user.target
分析上面的配置文件,我们大概能够将整个设置分为三个部分
- [unit]:unit本身的说明,以及与其他依赖daemon的设置,包括在什么服务之后才启动此unit之类的设置值。
- [service]、[socket]、[Timer]、[Mount]、[Path]:不同的unit类型就得要使用相对应的设置项目。我们使用sshd.service来当模板,所以这便就使用[Service]来设置。这个项目主要用来规范服务启动的脚本、环境配置文件名、重新启动的方式等。
- [Install]:这个项目就是此unit安装到哪个target里面去的意思。
至于配置文件内有些设置规则还得要说明一下。
- 设置项目通常是可以重复的,例如我可以重复设置两个After在配置文件中,不过,后面的设置会替换前面的。因此,如果你想要将设置值归零,可以使用【Afer=】的设置,亦即该项目的等号后面设么都没有,就将该设置归零了。
- 如果设置参数需要有【是/否】的项目(布尔值,boolean),你可以使用1、yes、true、on代表启动,用0、no、false、off代表关闭
- 空白行,开头为 # 或 ; 的那一行,都代表注释
[Unit]部分 | |
设置参数 | 参数意义说明 |
Description | 是当我们使用 systemctl list-units 时,会输出给管理员看的简易说明。当然,使用 systemctl status 输出的此服务的说明,也是这个项目 |
Documentation | 这个项目在提供管理员能够进一步的文件查询的功能。提供的文件可以是如下的内容:
|
After | 说明此unit是在哪个daemon启动之后才启动的意思。基本上仅是说明服务启动的顺序而已,并没有强制要求里面的服务一定要启动后,此unit才能启动。这与Requires的设置是有差异的。 |
Before | 与After的意义相反,是在什么服务启动前最好启动这个服务的意思。不过这仅是规范服务启动的顺序,并非强制要求的意思。 |
Requires | 明确的定义此unit需要在哪个daemon启动后才能够启动,就是设置依赖服务。如果在此项设置的前导服务没有启动,那么此unit就不会被启动 |
Wants | 与Requires刚好相反,规范的是这个unit之后最好还要启动什么服务比较好的意思。不过,并没有明确的规范,主要的目的是希望建立让用户比较好操作的环境。因此,这个Wants后面接的服务如果没有启动,其实不会影响到这个unit本身 |
Conflicts | 代表冲突的服务。亦即这个项目后面接的服务如果有启动,那么我们这个unit本身就不能启动。我们unit有启动,则此项目后的服务就不能启动。 |
[Service]部分 | |
设置参数 | 参数意义说明 |
Type | 说明这个daemon启动的方式,会影响到ExecStart,一般来说,有下面几种类型:
比较重要的项目大概是simlpe、forking与oneshot。 |
Environment | 可以指定启动脚本的环境设置文件,例如sshd.service的配置文件写入到/etc/sysconfig/sshd当中。你也可以使用Environment= 后面接多个不同的Shell变量来给予设置 |
ExecStart | 就是实际执行此daemon的命令或脚本程序。你也可以使用 ExecStartPre(之前)以及ExecStartPost(之后)两个设置项目来实际启动服务前,进行额外的命令操作。但是要特别注意的是,命令串仅接受【命令 参数 参数...】的格式,不能接受<、>、>>、|、&等特殊字符,很多的bash语法都不支持,所以,要使用这些特殊的字符时,最好直接写入到命令脚本里面去。不过,上述的语法也不是完全不能用,若要支持比较完整的bash语法,那你得要使用Type=oneshot才行,其他的Type不能支持这些字符 |
ExecStop | 与 systemctl stop 的执行有关,关闭此服务时所运行的命令 |
ExecReload | 与 systemctl reload有关的命令操作 |
Restart | 当设置 Restart=1 时,则当此daemon服务终止时,会再次启动此服务。举例来说,如果你在tty2使用命令行界面登陆,操作完毕后注销,基本上这个时候tty2的登陆界面等待你的登陆,那就是Restart的功能。除非使用 systemctl 强制将此服务关闭,否则这个服务会源源不断地重复产生 |
RemainAfterExit | 当设置为RemainAfterExit=1时,则当这个daemon所属地所有进程都终止之后,此服务会再次尝试启动,这对于Type=oneshot的服务很有帮助。 |
TimeoutSec | 若这个服务在启动或关闭时,因为某些缘故导致无法顺利【正常启动或正常结束】地情况下,则我们要等多久才进入【强制结束】的状态 |
KillMode | 可以是process、control-group、none其中一种,如果是process则daemon终止时,只会终止主要的进程(ExecStart 接地后面那串命令);如果是control-group时,则由此daemon所产生地其他control-group地进程,也都会被关闭;如果是none,则没有进程会被关闭。 |
RestartSec | 与Restart有点相关性,如果这个服务被关闭,然后需要重新启动时,大概要 sleep多少时间再重新启动地意思,默认是100ms(毫秒) |
[Install]部分 | |
设置参数 | 参数意义说明 |
WantedBy | 这个设置后面接的大部分是 *.target unit,意思是这个unit本身是依附于哪一个target unit。一般来说,大多服务性质的unit都是依附于multi-user.target |
Also | 当目前这个unit本身被enable时,Also后面接的unit也请enable的意思,也就是具有依赖性的服务可以写在这里。 |
Alias | 运行一个链接的别名的意思。当 systemctl enable相关的服务时,则此服务会进行链接文件的建立。以multi-user.target为例,这个家伙用来作为默认操作环境default.target的使用,因此当你设置成 default.target 时,这个 /etc/systemd/system/default.target就会链接到/usr/lib/systemd/system/multi-user.target。 |
应注意的是:管理员应使用man systemd.unit、man systemd.service、man systemd.socket、man systemd.target、man systemd.timer查询/etc/systemd/system/下面配置文件的语法,并使用 systemctl daemon-reload加载后,才能自行编写服务与管理服务。
五、远程连接服务器
1、什么是远程连接服务器
远程连接服务器通过文字或图形接口的方式来远程登录系统,让你在远程的终端前面登录 Linux 主机以取得可操作主机的接口(Shell),而登录后的操作感觉上就像坐在系统前面一样。
很多人会说,我用 FTP 时也要输入帐号与密码来登录啊?那与这个章节谈到的登录有何不同?最大的不同在于通过远程连接可以取得 Shell 来工作!用 SSH/Telnet/VNC 等方式取得的文字或图形 Shell 能够进行很多系统管理的任务,与单纯的 FTP 能进行的工作当然不同。
2、有哪些可供登录的类型
目前远程连接服务器的主要类型有哪些?如果以登录的连接界面来分类,基本上有文字接口与图形接口两种。
- 文字接口明文传输: Telnet、RSH 等位主,目前非常少用。
- 文字接口加密: SSH 为主,已经取代上述的 Telnet、RS好等明文传输方式。
- 图形接口: XDMCP、VNC、XRDP等较为常见。
3、什么是 SSH
SSH(Secure Shell)是专为远程登录会话和其他网络服务提供安全性的协议。SSH协议族可以用来进行远程控制,或在计算机之间传送文件。
功能:让远程让远程主机可以通过网络访问sshd服务,开始一个安全shell。
4、数据的明文传输与加密传输
所谓的明文传输就是: “当我们的数据包在网络上传输时,该数据包的内容为数据的原始格式”,也就是说,你使用 Telnet 等可远程主机时,不是要输入帐号和密码吗?那你的帐号和密码是以原本的数据格式传输,所以如果被类似 tcpdump 之类的监听软件获取到数据,那你的帐号、密码九有可能被窃取啦!
所谓的加密传输就是:将人们能看懂的原始电子数据经过一些运算,让这些数据变成没有意义的乱码(至少对人类来说),然后再让这个加密数据在网络上面传输。
说 SSH 比较安全,其实是通过 SSH 协议传输信息时,该信息在网络上面比较安全,因为数据是加密过的,即使被窃取,对方可能也不会知道数据内容为何,因此信息比较安全。但这不代表 SSH 这个通信协议就比较安全,两者意义不同!
六、文字接口连接服务器:SSH服务器
1、连接加密技术简介
什么是“数据加密”呢?简单地说,就是将人们能看懂的原始电子数据经过一些运算,让这些数据变成没有意义的乱码(至少对人类来说),然后再让这个加密数据在网络上面传输,而当用户想要查询这个数据时,再经过解密运算,将这些加密数据反推出原始的电子数据。
目前常见的网络数据包加密技术通常是通过所谓的 “非对称密钥系统”来处理的。主要是通过两把不一样的公钥与私钥来进行加密与解密的过程。由于这两把钥匙的作用是提供数据加解密的,所以在同一方向的连接中,这两把钥匙当然是需要成对的,它的作用分别如下:
- 公钥: 提供给远程主机进行数据加密的行为,也就是说,大家都能取得你的公钥来将数据加密的意思。
- 私钥: 远程主机使用你的公钥加密的数据,在本地端就能够使用私钥来进行解密。由于私钥很重要,因此私钥是不能够外流的,只能保护在自己的主机上。
由于每台主机都应该有自己的密钥(公钥与私钥),且公钥用来加密而私钥用来解密,其中私钥不可外流,但是网络连接是双向的,所以,每个人都应该要有对方的 “公钥” 才对!
SSH 服务端与客户端的连接步骤如下:
- 服务器建立公钥文件: 每一次启动 SSHD 服务时,该服务会主动去找 /etc/ssh/ssh_host*文件,若系统刚刚安装完成,由于没有这些公钥文件,因此 SSHD 会主动计算出这些需要的公钥文件,同时也会计算出服务器自己需要的私钥文件。
- 客户端主动连接要求:若客户端想要连接到 SSH 服务器,则需要使用适当的客户端程序来连接,包括 SSH、Pietty 等客户端程序。
- 服务器传送公钥文件给客户端:接收到客户端的要求后,服务器便将第一个步骤取得的公钥文件传送给 客户端 使用(此时应是明码传送,反正公钥本来就是给大家使用的)
- 客户端记录/比对服务器的公钥数据及根据服务端发送来的公钥对密码进行加密:若客户端第一次连接到此服务器,则会将服务器的公钥数据记录到客户端的用户主目录内的 ~/.ssh/known_hosts。若是已经记录过该服务器的公钥数据,则客户端会区比对此次接收到的与之前的记录是否有差异。若接收此公钥数据,则客户端根据服务器发送来的公钥数据对密码进行加密。
- 返回客户端的加密数据到服务器端:客户端将加密后的信息传送给服务器,服务器用自己的私钥解密,若密码正确,则用户登录成功。
此外在客户端的用户主目录下的 ~/.ssh/known_hosts 中会记录曾经连接过的主机的 Public Key,用于确认我们已连接上正确的服务器。
例题:
如何产生新的服务器端的 SSH 公钥与服务器自己使用的成对私钥。(服务端为root@server;客户端为kiosk@fundation7)
[root@server ~]# rm -rf /etc/ssh/ssh_host_* <==删除密钥文件
[root@server ~]# systemctl restart sshd.service
[root@server ~]# date ; ll /etc/ssh/ssh_host_*
Tue Jun 11 12:32:45 CST 2019
-rw-r-----. 1 root ssh_keys 227 Jun 11 12:32 /etc/ssh/ssh_host_ecdsa_key
-rw-r--r--. 1 root root 162 Jun 11 12:32 /etc/ssh/ssh_host_ecdsa_key.pub
-rw-r-----. 1 root ssh_keys 1679 Jun 11 12:32 /etc/ssh/ssh_host_rsa_key
-rw-r--r--. 1 root root 382 Jun 11 12:32 /etc/ssh/ssh_host_rsa_key.pub
#看一下上面输出的日期与文件的建立时间,刚刚建立的新公钥、私钥文件
[kiosk@foundation7 ~]$ ssh root@172.25.254.1 #由于服务端的公钥发生了变化,导致客户端的~/.ssh/known_hosts文件与服务端的公钥文件不同,所导致下面的错误
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that a host key has just been changed.
The fingerprint for the ECDSA key sent by the remote host is
8d:37:2c:23:83:6b:f5:25:d0:d7:05:ba:24:df:fe:d9.
Please contact your system administrator.
Add correct host key in /home/kiosk/.ssh/known_hosts to get rid of this message.
Offending ECDSA key in /home/kiosk/.ssh/known_hosts:1 <==冒号后面接的数字就是有问题的数据行号
ECDSA host key for 172.25.254.1 has changed and you have requested strict checking.
Host key verification failed.
[kiosk@foundation7 ~]$ rm -rf ~/.ssh/known_hosts #解决办法就是删除客户端的~/.ssh/known_hosts文件,或是删除~/.ssh/known_hosts文件中的IP为172.25.254.1的那一行(根据上面的提示,我们知道是第一行)
[kiosk@foundation7 ~]$ ssh root@172.25.254.1 #因为删除了~/.ssh/known_hosts文件,所以系统会重新询问你要不要加上公钥
The authenticity of host '172.25.254.1 (172.25.254.1)' can't be established.
ECDSA key fingerprint is 8d:37:2c:23:83:6b:f5:25:d0:d7:05:ba:24:df:fe:d9.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.25.254.1' (ECDSA) to the list of known hosts.
root@172.25.254.1's password:
Last login: Tue Jun 11 12:26:52 2019 from 172.25.254.7
2、启动 SSH 服务(sshd.service)
事实上,在我们使用的 Linux 系统当中,默认就已经含有 SSH 所有需要的软件了,包含了可以产生密码等协议的 OpenSSL 软件与 OpenSSH 软件。
需要注意的是,SSH 不但提供了 Shell 给我们使用,即是 SSH Protocol 的主要目的,同时也提供了一个较为安全的 FTP Server ,也就是 SSH-FTP Server 给我们当成是 FTP 来使用,所以,这个 SSHD 可以同时提供 Shell 与 FTP,而且都是架构在 Port 22 上面的。
3、SSH 客户端连接程序——Linux用户
如果你的客户端是 Linux 的话,那么恭喜你了,默认的情况下,你的系统已经有下面的所有指令,可以不必安装额外的软件。
(1)SSH:直接登录远程主机的指令
SSH 在 client 端使用的是 SSH 这个指令,这个指令可以连接到的版本(Version1、Version2),还可以指定非正规的 SSH Port(正规的 SSH Port为22)。
ssh [-f] [-o 参数项目] [-p 非标准端口] [帐号@]IP [命令]
选项与参数:
-f:需要配合后面的 [命令],不登录远程主机直接发送一个命令过去而已
-o:参数项目:主要的参数项目有:
ConnectTimeout=秒数:连接等待的秒数,较少等待的时间
StrictHostKeyChecking=[yes|no|ask]:默认是 ask,若要让 public key 主动假如 known_hosts ,则可以设置为 no 即可
-p:如果 sshd 服务启动在非标准的端口,需使用此项目
[命令]:不登录远程主机,直接发送命令过去。但与 -f 意义不太相同
【1】、案例一:直接连接登录到对方主机的方法(以登录本机为例):
[root@server ~]# ssh 127.0.0.1
The authenticity of host '127.0.0.1 (127.0.0.1)' can't be established.
ECDSA key fingerprint is 8d:37:2c:23:83:6b:f5:25:d0:d7:05:ba:24:df:fe:d9.
Are you sure you want to continue connecting (yes/no)? yes <==这里输入yes
Warning: Permanently added '127.0.0.1' (ECDSA) to the list of known hosts.
root@127.0.0.1's password: <==在这里输入 root 的密码即可!
Last login: Tue Jun 11 12:37:02 2019 from 172.25.254.7
[root@server ~]# exit <==离开这此的 SSH 连接
#由于 SSH 后面没有加上帐号,因此默认使用当前帐号来登录远程服务器
一般使用 SSH 登录远程主机,采用 “SSH 帐号主机IP” 的格式,即使用该主机的帐号登录的意思。但是很多朋友都不喜欢写帐号,也就是使用“SSH 主机IP” 的格式。要注意哦,如果不写帐号的话,那么会以本地端计算机的帐号来尝试登录远程。也就是说,如果近端与远程具有相同的帐号,那么不写帐号也没有关系,如上述的范例。
在上面出现的信息中,开头 ECDSA 的那行后面接的就是远程服务器的公钥指纹码,如果确定该指纹码没有问题,那么你就需要输入 yes 来将该指纹码写入服务器公钥记录文件(~/.ssh/known_hosts),以便对比该服务器的正确性。注意是要写 yes ,单纯输入 y 或 Y 是不会被接受的。此外,由于该主机的公钥已经被记录,因此未来重复使用 SSH 登录此主机时,就不会出现这个指纹码提示了。
【2】、案例二:使用 student 帐号登录本机
[root@server ~]# ssh student@127.0.0.1
student@127.0.0.1's password:
[student@server ~]$ exit
# 由于加入帐号,因此切换身份称为 student了。另外,因为127.0.0.1 曾登录过,
# 所以就不会再出现提示要添加主机公钥的信息了
【3】、登录对方主机,执行过命令后立刻离开的方式
[root@server ~]# ssh student@127.0.0.1 "find / &> ~/find1.log"
student@127.0.0.1's password: <==输入student用户的密码
# 此时你会发现画面卡住了,这是因为上面的命令造成的,你已经登录远程主机,
# 但是执行的命令尚未运行完,因此会在等待当中。那如何指定系统自己运行呢?
值的一提的是,后面的命令必须加 "" ,否则会在本机上执行该命令,而不是对方主机上。
【4】、与上题相同,让对方主机自己运行该命令,你立刻回到本地端主机继续工作
[root@server ~]# ssh -f student@127.0.0.1 "find / &> ~/find2.log"
student@127.0.0.1's password: <==输入student用户的密码
# 此时你会立刻注销 127.0.0.1,但 find 命令会自己在远程服务器运行
【5】、删除 known_hosts 后,重新使用 root连接到本地,且自动加上公钥记录
[root@server ~]# ssh -o StrictHostKeyChecking=no student@localhost
Warning: Permanently added 'localhost' (ECDSA) to the list of known hosts.
student@localhost's password:
#如上所示,不会问你 yes 或 no 啦!直接写入到 ~/.ssh/known_hosts中
(2)ssh的连接方式
【1】、ssh username@IP 文本方式连接(以username的身份进行连接)
以文本方式进行连接不能使用gedit,但是以图形方式连接可以使用gedit
【2】、ssh -X username@ip 图形方式连接(以username的身份进行连接)
可以通过命令'cheese'来打开摄像头
【3】、ssh username@ip -X 图形方式连接(以username的身份进行连接,同【2】,即参数可以加在中间,也可以加在后面)
可以通过命令'cheese'来打开摄像头
(3)服务器公钥记录文件:~/.ssh/known_hosts
当你登录远程服务器时,本机会主动利用接收到的服务器的 Public key 去比对 ~/.ssh/known_hosts 有无相关的公钥,然后进行下面的操作:
- 若接收的公钥尚未记录,则询问用户是否记录。若要记录(范例中回答 yes 的那个步骤)则写入 ~/.ssh/known_hosts 且执行后续工作;若不记录(回答 no )则不写入该文件,并且退出登录工作。
- 若接收的公钥已有记录,则比对记录是否相同,若相同则继续登录动作;若不相同,则出现警告信息,且离开登录的动作。这是客户端的自我保护功能,以避免你的服务器是被别人伪装的。
(4)模拟 FTP的文本传输方式:SFTP
SSH 是登录远程服务器进行工作,那如果你只是想要从远程服务器下载或上传文件呢?那就不是使用 SSH啦,而必须要使用 SFTP 或 SCP。这两个指令也都是使用 SSH 的通到(Port 22),只是模拟成 FTP 与复制的操作而已。我们先谈谈 SFTP,这个指令的用法与 SSH 很相似,只是 SSH 是用来登录,而 SFTP 用来上传/下载文件而已。
[root@server ~]# sftp student@localhost
student@localhost's password: <==这里请输入密码
Connected to localhost.
sftp> <==这里就是在等待你输入 FTP 相关命令的地方
进入到 SFTP 之后,就与在一般 FTP 模式下的操作方法没有两样了!下面我们就来谈谈 SFTP 这个接口下可使用的指令。
针对远程服务器主机(Server)的行为 | |
切换目录到 /etc/test 或其他目录 | cd /etc/test、cd PATH |
列出当前所在目录下的文件名 | ls dir |
建立目录 | mkdir directory |
删除目录 | rmdir directory |
显示当前所在的目录 | pwd |
更改文件或目录属组 | chgrp gid PATH |
更改文件或目录的属主 | chown uid PATH |
更改文件或目录的权限 | chmod 644 PATH 其中,644与权限有关 |
建立连接文件 | ln [-s] oldname newname |
删除文件或目录 | rm PATH |
更改文件或目录名称 | rename oldname newname |
查看帮助 | help |
离开远程主机 | exit、bye、quit |
针对本机(Client)的行尾(都加上l,L的小写) | |
切换目录到本机的 PATH当中 | lcd PATH |
列出当前本机所在目录下的文件名 | lls |
在本机建立目录 | lmkdir |
显示当前所在的本机目录 | lpwd |
针对资料上传/下载的操作 | |
将文件上传到远程主机 | put [本地文件] [远程] put [本地文件] 如果是后一种格式,则文件会存储到当前远程主机的目录下 |
将文件由远程主机下载回来 | get [远程文件] [本机] put [远程文件] 如果是后一种格式,则文件会存储到当前远程主机的目录下。可以使用通配符,例如:get *、get *.rpm |
例题:
假设 localhost 为远程服务器,且服务器上有 student 这个用户。你想要将本机的 /etc/hosts 上传到 student 用户主目录,并将 student 的 .bashrc 复制到本机的 /tmp 底下,该如何通过 SFTP 实现?
[root@server ~]# sftp student@localhost
student@localhost's password:
Connected to localhost.
sftp> lls /etc/hosts <==先看看本机有没有这个文件
/etc/hosts
sftp> pwd <==确认,远程主机是否位于student用户的家目录下
Remote working directory: /home/student
sftp> put /etc/hosts <==确认无误的话,就上传吧
Uploading /etc/hosts to /home/student/hosts
/etc/hosts 100% 187 0.2KB/s 00:00
sftp> ls <==确认,是否上传成功
file hosts
sftp> ls -a <==查看远程主机上,是否有隐藏文件 .bashrc
. .. .bash_history .bash_logout .bash_profile
.bashrc .cache .config .mozilla .viminfo
file hosts
sftp> get .bashrc /tmp <==有的话,就上传吧
Fetching /home/student/.bashrc to /tmp/.bashrc
/home/student/.bashrc 100% 231 0.2KB/s 00:00
sftp> lls -a /tmp <==查看本地的 /tmp目录下,是否有远程主机上传的 .bashrc文件
. etc2.tar.gz systemd-private-rOf7Ma top.txt
.. .font-unix systemd-private-S2HRdI .X0-lock
.bashrc .ICE-unix .Test-unix .X11-unix
.esd-0 log.txt text.txt .XIM-unix
sftp> exit <==离开
(5)文件异地直接复制:SCP
通常使用 SFTP 是因为可能不知道服务器上面已存在的文件名信息,如果已经知道服务器上的文件名,那么最简单的文件传输则是通过 SCP 这个指令。
查看博客:https://mp.csdn.net/postedit/83748596
4、SSHD 服务器详细配置(/etc/ssh/sshd_config)
基本上,所有的 SSHD 服务器的详细设置都放在 /etc/ssh/sshd_config 配置文件中。同时请注意,在配置文件内,只要是被注释的设置值(设置值前面加 “#”),即为 “默认值”,你可以依据它来修改。
[root@server ~]# vim /etc/ssh/sshd_config
### 1、关于 SSH Server 的整体设置,包含使用的 port,以及使用的密码算法方式
17 #Port 22
# SSH 默认使用 22 这个 port,也可以使用多个 Port,即重复使用 Port 这个设置项目
# 例如想要开放 SSHD 在 22 与 443,则多加一行内容为: port 443
# 然后重新启动 SSHD 就好了。不过,不建议修改 Port Number
19 #ListenAddress 0.0.0.0
# 监听的主机网卡。举个例子来说,如果有两个 IP,分别是 192.168.1.100 及 192.168.100.254
# 假设只想要让 192.168.1.100 可以监听 SSHD,那就这样写:
# "ListenAddress 192.168.1.100",默认值是监听所有接口的 SSH 要求
23 #Protocol 2
# 选择的 SSH 协议版本,可以是 1 也可以是 2 ,Redhat 7.x 默认支持 V2.
# 如果想要支持旧版的 V1,就需要使用 "Protocol 2,1"才行
### 2、说明主机的 Private Key 放置的文件,默认使用下面的文件即可
25 # HostKey for protocol version 1
26 #HostKey /etc/ssh/ssh_host_key <== SSH version 1 使用的私钥
27 # HostKeys for protocol version 2
28 HostKey /etc/ssh/ssh_host_rsa_key <==SSH version 2 使用的RSA私钥
29 #HostKey /etc/ssh/ssh_host_dsa_key <==SSH version 2 使用的DSA私钥
30 HostKey /etc/ssh/ssh_host_ecdsa_key <==SSH version 2 使用的ECDSA私钥
### 3、关于登录文件的信息数据放置与 daemon 的名称
42 SyslogFacility AUTHPRIV
# 当有人使用 SSH 登录系统时,SSH 会记录信息,这个信息要记录在 Daemon Name 下面
# 默认是以 AUTH 来设置的,即 /var/log/secure 里面
# 其他可用的 Daemon Name 为: DAEMON、USER、AUTH、LOCAL0、LOCAL1、LOCAL2、LOCAL3、LOCAL4、LOCAL5
43 #LogLevel INFO
# 日志的等级
### 4、安全设置项目。极重要。
### 4.1、登录设置部分
47 #LoginGraceTime 2m
# 当连上 SSH Server 之后,就会出现输入密码的界面,在该界面中,
# 经过多长时间内没有成功连上 SSH Server 就强迫断开连接。若无单位则默认时间是秒
48 #PermitRootLogin yes
# 是否允许 root 登录。默认是允许的,但是建议设置为 no
49 #StrictModes yes
# 是否让 sshd 去检查用户主目录或相关文件的权限数据
# 这是为了担心用户将某些重要文件的权限设错,可能会导致一些问题所致
# 例如用户的 ~.ssh/ 权限设措,某些情况下会不许用户登录
54 #PubkeyAuthentication yes
58 AuthorizedKeysFile .ssh/authorized_keys
# 是否允许用户自行使用成对的密钥系统进行登录,仅针对 Version 2
# 至于自定义的公钥数据就放置在用户主目录下的 ~.ssh/authorized_keys 内
76 #PasswordAuthentication yes
# 密码验证当然是需要的,所以这里写 yes
77 #PermitEmptyPasswords no
# 如果上面哪一项设置为 yes 的话,这一项最好设置为 no
# 这个项目用于设置是否允许以空的密码登录,当然不许
### 4.2、认证部分
66 #RhostsRSAAuthentication no
# 这个选项是专门给 Version 1 用的,使用 rhosts 文件在 /etc/hosts.equiv
68 #HostbasedAuthentication no
# 这个项目与上面的项目类似,不过是给 Version 2 使用的
73 #IgnoreRhosts yes
# 是否取消 ~/.ssh/.rhosts 来作为i认证,当然是
71 #IgnoreUserKnownHosts no
# 是否忽略用户主目录内的 ~/.ssh/known_hosts 这个文件所记录的内容?
# 当然不要忽略,所以这里就是 no
82 ChallengeResponseAuthentication no
# 允许任何的密码认证,所以,任何 login.conf 规定的认证方式,均可使用
# 但目前我们比较喜欢使用 PAM 模块帮忙管理认证,因此这个选项可以设置为 no
111 UsePAM yes
# 利用 PAM 管理用户认证有很多好处,可以记录与管理
# 所以这里我们建议使用 UsePAM 且 ChallengeResponseAuthentication 设置为 no
###4.3、与 Kerberos 有关的参数设置。因为我们没有 Kerberos 主机,所以下面的不用设置
84 # Kerberos options
85 #KerberosAuthentication no
86 #KerberosOrLocalPasswd yes
87 #KerberosTicketCleanup yes
88 #KerberosGetAFSToken no
89 #KerberosUseKuserok yes
###4.4、下面是有关在 X-Window 下使用的相关设置
117 X11Forwarding yes
118 #X11DisplayOffset 10
119 #X11UseLocalhost yes
# 比较重要的是 X11Forwarding 项目,它可以让窗口的数据通过 SSH 连接来传送
###4.5、登录后的项目
120 #PrintMotd yes
# 登录后是否显示出一些信息?例如上次登录的时间、地点等,默认是 yes
# 也就是打印出 /etc/motd 这个文件的内容。但是,如果为了安全,可以考虑为 no
121 #PrintLastLog yes
# 显示上此登录的信息,默认也是 yes
122 #TCPKeepAlive yes
# 当实现连接后,服务器会一直发送 TCP 数据包给客户端,用以判断对方是否一直存在连接
# 不过,如果连接时中间的路由器暂时停止服务及秒钟,也会让连接中断
# 在这个情况下,任何一端死掉后,SSH 可以立刻知道,而不会有僵尸进程的出现
# 但如果网络或路由器常常不稳定,可以设置为 no
132 #MaxStartups 10:30:100
# 同时允许几个尚未登录的连接界面?当我们连上 SSH ,但是尚未输入密码时,
# 这个时候就是所谓的连接界面。在这个连接界面中,为了保护主机,
# 需要设置最大值,默认最多有 100 个连接界面,而已经建立连接的不计算在这 100 个当中
###5、关于 SFTP 服务与其他的设置项目
147 Subsystem sftp /usr/libexec/openssh/sftp-server
130 #UseDNS yes
# 一般来说,为了判断客户端来源是否为正常合法的,会使用 DNS 去反查客户端的主机名
# 不过如果是在内网互联,这项目设置为 no 会让连接速度比较快
如果你修改过上面这个文件(/etc/ssh/sshd_config),那么就必须重新启动一次 SSHD 才行,也就是:systemctl restart sshd
5、制作不用密码可立即登录的 SSH 用户(实现免密登录)
(1)实现客户端 client——>服务端 server 之间的免密登录
我们可以将 Client 产生的 公钥 复制到 Server 当中,所以,以后 Client 登录 Server 时,由于 Client 端的公钥与 Server 端的公钥相同,且 Client 端又有该公钥对应的私钥数据 ,因此,可以立即进入数据传输接口当中,而不需要再输入密码。其实现步骤如下:
- 客户端建立两把钥匙:想一想,在密钥系统中,是公钥比较重要还是私钥比较重要?当然是私钥比较重要!因此私钥才是解密的关键啊!所以,这两把钥匙当然得在发起连接的客户端配置才对。利用的命令为 ssh-keygen。
- 客户端放置好私钥文件:将 Private Key 放在 Client 上面的用户主目录中,也就是 $HOME/.ssh/,并且要注意权限哦。
- 将公钥放置到服务器的正确目录与文件中:最后,将 Public Key 放置在任何一个你想要用来登录的服务器端的某 User 用户主目录内的 .ssh/ authorized_keys中即可完成整个程序。
【1】、客户端建立两把钥匙
要注意的是我们有多种密码算法,如果不指定特殊的算法,则默认是以 RSA 算法来处理:
[root@client ~]# ls .ssh/
[root@client ~]# ssh-keygen <==可选 rsa、dsa、ecdsa,这里使用默认的方法建立密钥
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa): <==输入 Enter
Enter passphrase (empty for no passphrase): <== 输入 Enter
Enter same passphrase again: <==再输入一次 Enter 吧
Your identification has been saved in /root/.ssh/id_rsa. <==私钥文件
Your public key has been saved in /root/.ssh/id_rsa.pub. <==公钥文件
The key fingerprint is:
e5:83:1d:59:f4:7f:ae:95:77:b1:81:4f:a3:e8:ca:ba root@client
The key's randomart image is:
+--[ RSA 2048]----+
| .o |
| o . |
| + . |
| = . .. |
| S + . =o|
| .. +.B|
| . . +=|
| . . oo|
| Eoo.. . |
+-----------------+
[root@client ~]# ll -d ~/.ssh/ ; ll ~/.ssh/
drwx------. 2 root root 36 Jun 12 12:41 /root/.ssh/
total 8
-rw-------. 1 root root 1679 Jun 12 12:41 id_rsa <==私钥文件
-rw-r--r--. 1 root root 393 Jun 12 12:41 id_rsa.pub <==公钥文件
- 请注意上面我的身份是 root ,所以当我执行 ssh-keygen 时,才会在我的用户主目录下的 .ssh/ 目录里面产生需要的两把 Keys,分别是 私钥(id_rsa)与公钥(id_rsa.pub)。
- ~/.ssh/ 目录必须要是 700 的权限才行!
- 另外,一个特别需要注意的就是那么 id_rsa 的文件权限,它必须是 -rw------- 且属于 root 自己才行,否则在未来密钥比对的过程当中,可能会被判断为危险而无法成功以公私钥成对文件的机制来实现连接哦。其实,建立私钥后默认的权限与文件名放置位置都是正确的,你只要检查过没问题即可。
【2】、将客户端的公钥数据上传到服务端
[root@client ~]# scp ~/.ssh/id_rsa.pub root@172.25.254.1:~
# 上传到 服务端的 root 的用户主目录下面即可
【3】、将客户端传来的公钥数据放置到服务端的正确目录中
1、查看是否有 .ssh 目录,若没有,则需要手动建立
[root@server ~]# ll -d .ssh
drwx------. 2 root root 24 Jun 11 15:08 .ssh
# 权限设置中,务必是 700,且属于本人的帐号与组才行
2、将公钥数据内的数据使用 cat 转存到 authorized_keys 内
[root@server ~]# ll *pub <==id_rsa.pub文件确实存在
-rw-r--r--. 1 root root 393 Jun 12 15:13 id_rsa.pub
[root@server ~]# cat id_rsa.pub >> .ssh/authorized_keys
[root@server ~]# ll -d .ssh/authorized_keys
-rw-r--r--. 1 root root 393 Jun 12 15:20 .ssh/authorized_keys
# 这个文件的权限需要是 644 才可以,不可以搞混了
【4】、测试:看 client——>server 是否是免密的
但是当 server 端将公钥 authorized_keys 删除之后,还是需要密码的。
(2)实现服务端 server——>客户端 client 之间的免密登录(不同于(1)的方法)
【1】、客户端建立两把钥匙——做法同(1)
【2】、加密服务(本机加密)——生成 authorized_keys 目录
有三种方法:
- 第一种方法:使用 ssh-copy-id 命令(在 client 机上执行 ssh-copy-id -i id_rsa.pub root@172.25.254.2 命令,注意是给本机加密,输入的ip地址也是 client 机的。)也可以使用命令:ssh-copy-id server(因为ssh-copy-id命令默认发送的就是公钥id_rsa.pub)
- 第二种方法:使用 scp 命令(在 client 机上执行 scp ~/.ssh/id_rsa.pub root@172.25.254.2:~/.ssh/authorized_keys)
- 第三种方法:通过手工复制(在 client 机上执行 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys)
值的注意的是:
- 无论是上述那种方法,都要保证 authorized_keys 文件的权限为 644。
- 也相当于实现了 client——client之间的免密
这里采用第一种方法。
【3】、分发私钥
在 client 机上执行 scp id_rsa root@172.25.254.1:/root/.ssh 命令,该命令主以爱是完成将私钥文件 id_rsa 传给 server 机,故其中的 ip 地址也是 server 机的。
值的注意的是:
相当于实现了 server ——> client 的免密,但是并没有实现 client ——> server的免密
【4】、测试:看 server——>client 是否是免密的
但是当 server 端将私钥 id_rsa 删除之后,还是需要密码的。
6、简易安全设置(sshd 的安全设定)
SSHD 所谓的“安全”其实指的是 SSHD 的数据是加密过的,所以它的数据在 Internet 上面传递时是比较安全的。至于 SSHD 这个服务本身就不是那样安全了,所以说,如果不是必须将 SSHD 对 Internet 开放可登录的话,那么,就尽量局限在几个小范围内的 IP 或主机名,这是很重要的。
关于安全的设置方面,需要注意的地方分别可以由下面这三方面来进行:
- 服务器软件本身的设置强化:/etc/ssh/sshd_config
- TCP Wrapper的使用:/etc/hosts.allow、/etc/hosts.deny
(1)服务器软件本身的设置强化:/etc/ssh/sshd_config
【1】、设定:不允许 root 远程登录
<1>在服务端(172.25.254.1)进行配置
[root@server ~]# vim /etc/ssh/sshd_config
78 PasswordAuthentication yes
48 PermitRootLogin no
[root@server ~]# systemctl restart sshd.service
PasswordAuthentication yes和将其注释掉是一样的效果,要想起到相反的效果,需要写为PasswordAuthentication no,配置文件中别的相似的命令也是类似的。
<2>在客户端(172.25.254.2)进行测试
ssh root@172.25.254.1时,会显示permission denied;而普通用户可以登陆,即ssh student@172.25.254.1,通过输入密码,可以登陆成功。
上面登录成功与否,也可以通过查看 server 端的 /var/log/secure 文件来确定。
【2】、设定:允许 root 登录,同时也允许 student 登录
<1>在服务端(172.25.254.1)进行配置
[root@server ~]# vim /etc/ssh/sshd_config
78 PasswordAuthentication yes
48 #PermitRootLogin yes
49 AllowUsers student #在文件的任意地方添加这行内容
[root@server ~]# systemctl restart sshd.service
<2>在客户端(172.25.254.2)进行测试
ssh root@172.25.254.1时,会显示permission denied;而普通用户student可以登陆,即ssh student@172.25.254.1,通过输入密码,可以登陆成功;别的普通用户(比如:xin)不可以登陆,即ssh xin@172.25.254.1,会显示permission denied。
注意:
- 在使用白名单(Allowusers student)时,只允许student用户登陆,别的用户通通不允许登陆(root)用户也是如此,即不允许登陆)
- 如果白名单中有多个用户,那么用空格隔开。(通过man 5 sshd_config来查看sshd_config文件的帮助文档)
注意:root 能否登录,需要同时查看 PermitRootLogin 、AllowUsers 和 DenyUsers
- PermitRootLogin 中允许 root 登录,而 AllowUsers 中却没有 root,那么 root 是不可以登录的
- 同理,PermitRootLogin 中不允许 root 登录,而 AllowUsers 中却有 root,那么 root 是不可以登录的
【3】、设定:允许 root 登录,同时也允许 student 、xin 登录
<1>在服务端(172.25.254.1)进行配置
[root@server ~]# vim /etc/ssh/sshd_config
78 PasswordAuthentication yes
48 #PermitRootLogin yes
49 AllowUsers student xin #在文件的任意地方添加这行内容
[root@server ~]# systemctl restart sshd.service
<2>在客户端(172.25.254.2)进行测试
ssh root@172.25.254.1时,会显示permission denied;而普通用户student可以登陆,即ssh student@172.25.254.1,通过输入密码,可以登陆成功;别的普通用户(比如:xin)可以登陆,即ssh xin@172.25.254.1,通过输入密码,可以登陆成功。
【4】、设定 root 能够登录,student 不能登录
<1>在服务端(172.25.254.1)进行配置
[root@server ~]# vim /etc/ssh/sshd_config
78 PasswordAuthentication yes
48 #PermitRootLogin yes
49 #AllowUsers student xin #将 AllowUsers 这行注释
50 DenyUsers student #在该文件的任意地方添加这行
[root@server ~]# systemctl restart sshd.service
<2>在客户端(172.25.254.2)进行测试
ssh student@172.25.254.1时,会显示permission denied;而别的用户root不可以登陆,即ssh roo@172.25.254.1,通过输入密码,可以登陆成功;别的普通用户(比如:xin)也可以登陆,即ssh xin@172.25.254.1,通过输入密码,可以登陆成功。
注意:
- 在使用黑名单(Denyusers student)时,不允许student用户登陆,别的用户通通都可以登陆(root)用户也是如此,即允许登陆
- 如果黑名单中有多个用户,那么用空格隔开。(通过man 5 sshd_config来查看sshd_config文件的帮助文档)
【5】、设定 root 不能登录,student 也不能登录
<1>在服务端(172.25.254.1)进行配置
[root@server ~]# vim /etc/ssh/sshd_config
78 PasswordAuthentication yes
48 #PermitRootLogin yes
49 #AllowUsers student xin
50 DenyUsers student root
[root@server ~]# systemctl restart sshd.service
<2>在客户端(172.25.254.2)进行测试
ssh student@172.25.254.1时,会显示permission denied;而别的用户root不可以登陆,即ssh roo@172.25.254.1,会显示permission denied;别的普通用户(比如:xin)也可以登陆,即ssh xin@172.25.254.1,通过输入密码,可以登陆成功。
(2)/etc/hosts.allow 及 /etc/hosts.deny
如果还是一台测试机,那么需要将设定值还原回来,再进行下面的测试
[root@server ~]# vim /etc/ssh/sshd_config
48 #PermitRootLogin yes
49 #AllowUsers student xin #将这一行注释
50 #DenyUsers student root #将这一行注释
80 PasswordAuthentication yes
[root@server ~]# systemctl restart sshd
举例来说,你的 SSHD 只想让本机及 LAN 内的主机能够登录的话,那就这样操作:
[root@server ~]# vim /etc/hosts.allow
11 sshd: 127.0.0.1 172.25.254.0/24 #在文件的最后一行添加此内容
[root@server ~]# vim /etc/hosts.deny
14 sshd: ALL #在文件的最后一行添加此内容
7、添加sshd登陆信息
vim /etc/motd 文件的内容就是登陆后显示的信息
【1】、示例1:填写的是“你好,欢迎登陆“
<1>在服务端(172.25.254.1)编辑配置文件/etc/motd
[root@server ~]# vim /etc/motd
你好,欢迎登录
<2>在客户端(172.25.254.2)进行测试
【2】、示例2:填写的自己的信息
<1>在服务端(172.25.254.1)编辑配置文件/etc/motd
[root@server ~]# vim /etc/motd
HOSTNAME:server
IP:172.25.254.1
SERVICE=sshd
<2>在客户端(172.25.254.2)进行测试
注意:这里不是修改配置文件,而是重新编写一个文件,所以不用重启服务。
例如:这个配置文件是在服务端中进行编写,编写的是自己的信息,那么当客户机通过ssh服务连接时,连接成功时,会显示这个信息。
七、SSH 服务器的高级应用
1、在非标准端口启动 SSH(非 Port 22)
(1)设定 SSH 在 Port 22 及 23 两个端口监听的方式
请注意:
- Port 23 不能够被占用
- 注意一下,不要将 Port 开放杂ui某些已知的端口上,例如你开放在 Port 80 的话,那你就没有办法启动正常的 apche 服务啦!
[root@server ~]# vim /etc/ssh/sshd_config
17 Port 22 #将这一行的 # 去掉
18 Port 23 #添加这一行
[root@server ~]# systemctl restart sshd.service
[root@server ~]# netstat -antulpe | grep ssh #我们会发现22、23端口都找不到,这是因为 Selinux 所导致的
tcp 0 0 172.25.254.1:22 172.25.254.7:37056 ESTABLISHED 0 34598 1556/sshd: root@pts
1、在 /var/log/audit/audit.log 中找出与 SSH 有关的 AVC 信息,并转为本地模块
[root@server ~]# cat /var/log/audit/audit.log | grep AVC | grep ssh | audit2allow -m sshlocal > sshlocal.te <==扩展名要是 .te 才行
[root@server ~]# grep sshd_t /var/log/audit/audit.log | audit2allow -M sshlocal <==sshlocal 就是刚刚建立的 .te 文件名
******************** IMPORTANT ***********************
To make this policy package active, execute:
semodule -i sshlocal.pp <== 这个命令会去编译这个重要的 .pp 模块
2、将这个模块加载到系统的 SELinux 管理机制中
[root@server ~]# semodule -i sshlocal.pp
3、再重新启动 SSHD 并且查看端口
[root@server ~]# systemctl restart sshd.service
[root@server ~]# netstat -antulpe | grep sshd
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 0 171572 10194/sshd
tcp 0 0 0.0.0.0:23 0.0.0.0:* LISTEN 0 171568 10194/sshd
tcp 0 0 172.25.254.1:22 172.25.254.7:37056 ESTABLISHED 0 34598 1556/sshd: root@pts
tcp6 0 0 :::22 :::* LISTEN 0 171574 10194/sshd
tcp6 0 0 :::23 :::* LISTEN 0 171570 10194/sshd
(2)非标准端口的连接方式
由于默认的 SSH、SCP、SFTP 都是连接到 Port 22 的,那么如何使这些指令连接到 Port 23 呢?我们使用 SSH 来练习好了:
2、以 rsync 进行同步镜像备份
常用的备份指令包括 tar、dd、cp 等,现在介绍另外一种备份指令 rsync。
rsync 可以作为一个相当棒的异地备份系统的备份指令,原因有如下的两点
- 因为 rsync 可以答道类似 “镜像(Mirro)的功能”;
- rsync 不但传输的速度快,而且在传输时,可以比对本地端与远程主机欲复制的文件内容,而仅复制两端有差异的文件而已,所以传输的时间就相对降低很多!
rsync 的传输方式至少可以通过两种方式来工作:
- 在本机上直接运行,用法几乎与 cp 一模一样,例如:rsync -av /etc /tmp(将 /etc 内的数据备份到 /tmp/etc 内)
- 通过 ssh 的信道在 Server / Client 之间传输数据,例如:rsync -av -e ssh username@ip:/etc /tmp(将 ip地址为 ip 上的 /etc 备份到本地主机的 /tmp 内 )