Security基础(一):Linux基本防护措施、使用sudo分配管理权限、提高SSH服务安全
一、Linux基本防护措施
目标:
本案例要求练习Linux系统的基本防护措施,完成以下任务:
- 修改用户zhangsan的账号属性,设置为2015-12-31日失效(禁止登录)
- 锁定用户lisi的账户,使其无法登录,验证效果后解除锁定
- 锁定文件/etc/resolv.conf、/etc/hosts,以防止其内容被无意中修改
- 修改tty终端提示,使得登录前看到的第一行文本为“Windows Server 2012 Enterprise R2”,第二行文本为“NT 6.2 Hybrid”
步骤:
步骤一:修改用户zhangsan的账户属性,设置为2015-12-31日失效(禁止登录)
1)未过期的用户账号可以正常登录
以用户zhangsan登录测试。
2)失效的用户将无法登录
使用chage命令将用户zhangsan的账户设为当前已失效(比如前一天):
[root@svr7 ~]# date
2015年 05月 16日 星期六 14:16:25 CST
[root@svr7 ~]# chage -E 2015-05-15 zhangsan //设为当日的前一天
尝试以用户zhangsan重新登录,输入正确的用户名、密码后直接闪退,返回登录页,说明此帐号已失效。
3)重设用户zhangsan的属性,将失效时间设为2015-12-31
[root@svr7 ~]# chage -E 2015-12-31 zhangsan //修改失效日期
[root@svr7 ~]# chage -l zhangsan //查看账户年龄信息
Last password change : May 15, 2015
Password expires : never
Password inactive : never
Account expires : Dec 31, 2015
Minimum number of days between password change : 0
Maximum number of days between password change : 99999
Number of days of warning before password expires : 7
步骤二:锁定用户lisi的账户,使其无法登录,验证效果后解除锁定
1)未锁定的用户账号可以正常登录
以用户lisi登录测试。
2)锁定用户账号
使用passwd或usermod命令将用户lisi的账户锁定。
[root@svr7 ~]# passwd -l lisi //锁定用户账号
锁定用户 lisi 的密码 。
passwd: 操作成功
[root@svr7 ~]# passwd -S lisi //查看状态
lisi LK 2013-08-14 0 99999 7 -1 (密码已被锁定。)
3)验证用户lisi已无法登录,说明锁定生效
输入正确的用户名、密码,始终提示“Login incorrect”,无法登录。
4)解除对用户lisi的锁定
[root@svr7 ~]# passwd -u lisi //解锁用户账号
解锁用户 lisi 的密码 。
passwd: 操作成功
[root@svr7 ~]# passwd -S lisi //查看状态
lisi PS 2013-08-14 0 99999 7 -1 (密码已设置,使用 SHA512 加密。)
步骤三:锁定文件/etc/resolv.conf、/etc/hosts
1)使用chattr锁定文件,lsattr确认结果
[root@svr7 ~]# chattr +i /etc/resolv.conf /etc/hosts
[root@svr7 ~]# lsattr /etc/resolv.conf /etc/hosts
----i--------e- /etc/resolv.conf
----i--------e- /etc/hosts
2)测试文件锁定效果
[root@svr7 ~]# rm -rf /etc/resolv.conf
rm: 无法删除"/etc/resolv.conf": 不允许的操作
[root@svr7 ~]# echo "192.168.4.1 gateway.tarena.com" >> /etc/hosts
bash: /etc/hosts: 权限不够
3)恢复这两个文件原有的属性(避免对后续实验造成影响)
[root@svr7 ~]# chattr -i /etc/resolv.conf /etc/hosts
[root@svr7 ~]# lsattr /etc/resolv.conf /etc/hosts
-------------e- /etc/resolv.conf
-------------e- /etc/hosts
步骤四:修改tty登录的提示信息,隐藏系统版本
1)备份原有的/etc/issue配置文件,然后按照要求改写内容
[root@svr7 ~]# cat /etc/issue //确认原始文件
Red Hat Enterprise Linux Server release 6.5 (Santiago)
Kernel \r on an \m
[root@svr7 ~]# cp /etc/issue /etc/issue.origin //备份文件
[root@svr7 ~]# vim /etc/issue //修改文件内容
Windows Server 2012 Enterprise R2
NT 6.2 Hybrid
2)测试版本伪装效果
退出已登录的tty终端,或者重启Linux系统,刷新后的终端提示信息会变成自定义的文本内容,如下图所示。
二、使用sudo分配管理权限
目标:
本案例要求利用sudo机制分配管理操作权限,主要完成以下任务:
- 为sudo机制启用日志记录,以便跟踪sudo执行操作
- 允许网站运营专员tradm通过sudo方式控制httpd、mysqld服务的运行
- 允许用户ugadm通过sudo方式添加/删除/修改除root以外的用户账号
- 允许wheel组成员以特权执行/usr/bin/下的命令
步骤:
步骤一:为sudo机制启用日志记录,以便跟踪sudo执行操作
1)修改/etc/sudoers配置,添加日志设置
[root@svr7 ~]# visudo
Defaults logfile="/var/log/sudo"
.. ..
2)以root(默认有所有权限)执行sudo操作
[root@svr7 ~]# sudo -l //查看授权的sudo操作
匹配此主机上 root 的默认条目:
logfile=/var/log/sudo, requiretty, !visiblepw, always_set_home, env_reset, env_keep="COLORS
DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS", env_keep+="MAIL PS1 PS2 QTDIR USERNAME
LANG LC_ADDRESS LC_CTYPE", env_keep+="LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT
LC_MESSAGES", env_keep+="LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE",
env_keep+="LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY",
secure_path=/sbin\:/bin\:/usr/sbin\:/usr/bin
用户 root 可以在该主机上运行以下命令:
(ALL) ALL
3)确认日志记录已生效
[root@svr7 ~]# tail /var/log/sudo
.. ..
May 16 22:14:49 : root : TTY=pts/1 ; PWD=/root ; USER=root ; COMMAND=list
步骤二:允许网站运营专员tradm通过sudo方式控制httpd、mysqld服务的运行
1)修改/etc/sudoers配置
为tradm授予相关脚本的执行权限,允许通过servivce工具来管理httpd、mysqld服务,或者直接执行这两个脚本。
[root@svr7 ~]# visudo
.. ..
Cmnd_Alias LAMP_CTRL=/sbin/service httpd *, /sbin/service mysqld, /etc/init.d/ht
tpd, /etc/init.d/mysqld
tradm localhost,svr7=LAMP_CTRL
2)切换为tradm用户,并验证sudo执行权限
[root@svr7 ~]# su - tradm
[tradm@svr7 ~]$ sudo -l
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for tradm: //验证用户tradm的口令
.. ..
用户 tradm 可以在该主机上运行以下命令:
(root) /sbin/service httpd *, /sbin/service mysqld *, /etc/init.d/httpd,
/etc/init.d/mysqld
[tradm@svr7 ~]$ service mysqld start //不用sudo时启动服务失败
touch: 无法创建"/var/log/mysqld.log": 权限不够
chown: 正在更改"/var/log/mysqld.log" 的所有者: 不允许的操作
[失败]
.. ..
[tradm@svr7 ~]$ sudo service mysqld start //通过sudo启动服务成功
正在启动 mysqld: [确定]
步骤三:允许用户ugadm通过sudo方式添加/删除/修改除root以外的用户账号
1)修改/etc/sudoers配置
为ugadm授予用户管理相关命令的执行权限,例外程序以!符号取反,放在后面。在执行相关程序时,可以利用通配符*。
[root@svr7 ~]# visudo
.. ..
Cmnd_Alias UADM_CTRL=/usr/bin/passwd,!/usr/bin/passwd root,/usr/sbin/user*,
!/usr/sbin/user* * root
ugadm localhost,svr7=UADM_CTRL
2)切换为ugadm用户,验证sudo权限
可以通过sudo方式来添加/删除/修改普通用户:
[root@svr7 ~]# su – ugadm
[ugadm@svr7 ~]$ sudo -l
.. ..
用户 ugadm 可以在该主机上运行以下命令:
(root) /usr/bin/passwd, !/usr/bin/passwd root, /usr/sbin/user*,
!/usr/sbin/user* * root
[ugadm@svr7 ~]$ sudo useradd newuser01 //可以添加用户
[ugadm@svr7 ~]$ sudo passwd newuser01 //可以修改普通用户的口令
更改用户 newuser01 的密码 。
新的 密码:
重新输入新的 密码:
passwd: 所有的身份验证令牌已经成功更新。
[ugadm@svr7 ~]$ sudo usermod -L newuser01 //可以修改用户属性
[ugadm@svr7 ~]$ sudo userdel -r newuser01 //可以删除用户账号
但是不能修改root用户的属性:
[ugadm@svr7 ~]$ sudo usermod -L root
对不起,用户 ugadm 无权以 root 的身份在 svr7.tarena.com 上
执行 /usr/sbin/usermod -L root。
[ugadm@svr7 ~]$ sudo passwd root
对不起,用户 ugadm 无权以 root 的身份在 svr7.tarena.com 上
执行 /usr/bin/passwd root。
步骤四:允许wheel组成员以特权执行/bin/下的所有命令
此案例用来展示sudo的便利性及设置不当带来的危险性,生产环境下慎用。
实现时参考下列操作:
[root@svr7 ~]# visudo
.. ..
%wheel localhost,svr7=/bin/*
[root@svr7 ~]# usermod -a -G wheel zengye
[zengye@svr7 ~]$ sudo -l
.. ..
用户 zengye 可以在该主机上运行以下命令:
(root) /bin/*
[zengye@svr7 ~]$ sudo /bin/bash //与sudo –i 等效,表示初始化登录
[root@svr7 zengye]# //直接成root了
注意:类Shell的程序不要允许用户sudo执行,否则等同于开放所有root权限。
比方说,如果将/bin/bash复制为/sbin/serv1ce(名称可以有一定迷惑性),然后夹杂在其他正常命令里一起授权给用户tradm,则用户tradm执行sudo serv1ce后就具有了root的身份。
[zengye@svr7 ~]$ sudo serv1ce //执行伪装的Shell程序
[sudo] password for zengye: //验证用户口令
[root@svr7 zengye]# whoami //查看当前身份
root
三、提高SSH服务安全
目标:
本案例要求提高Linux主机上SSH服务端的安全性,完成以下任务:
- 配置基本安全策略(禁止root、禁止空口令)
- 针对SSH访问采用仅允许的策略,未明确列出的用户一概拒绝登录
- 实现密钥验证登录(私钥口令)、免密码登入(无私钥口令)
- 确认密钥验证使用正常后,禁用口令验证
步骤:
步骤一:配置基本安全策略
1)调整sshd服务配置,并重载服务
[root@svr7 ~]# vim /etc/ssh/sshd_config
.. ..
Protocol 2 //去掉SSH协议V1
PermitRootLogin no //禁止root用户登录
PermitEmptyPasswords no //禁止密码为空的用户登录
.. ..
[root@svr7 ~]# service sshd reload
重新载入 sshd: [确定]
2)测试基本安全策略
尝试以root用户SSH登录,失败:
[root@svr7 ~]# ssh root@192.168.4.7
root@192.168.4.7's password:
Permission denied, please try again.
将服务器上用户kate的密码设为空,尝试SSH登录,也会失败:
[root@svr7 ~]# passwd -d kate //清空用户口令
清除用户的密码 kate。
passwd: 操作成功
[root@svr7 ~]# ssh kate@192.168.4.7
kate@192.168.4.7's password:
Permission denied, please try again.
步骤二:针对SSH访问采用仅允许的策略,未明确列出的用户一概拒绝登录
1)调整sshd服务配置,添加AllowUsers策略,仅允许用户zengye、john、ugadm,其中ugadm只能从网段192.168.4.0/24登录。
[root@svr7 ~]# vim /etc/ssh/sshd_config
.. ..
AllowUsers zengye john ugadm@192.168.4.0/24
[root@svr7 ~]# service sshd reload
重新载入 sshd: [确定]
2)验证SSH访问控制,未授权的用户将拒绝登录。
[root@pc205 ~]# ssh ugadm@192.168.4.7 //已授权的用户允许登录
ugadm@192.168.4.7's password:
[ugadm@svr7 ~]$ exit
[root@pc205 ~]# ssh zhangsan@192.168.4.7 //未授权的用户被拒绝登录
zhangsan@192.168.4.7's password:
Permission denied, please try again.
步骤三:实现密钥对验证登录(私钥口令)、免密码登入(无私钥口令)
1)准备客户机测试环境
在客户机pc205上创建两个测试用户:mike、nono。其中mike将用来实现有私钥口令保护的SSH登录,而nono用来实现无私钥口令保护的SSH登录(免密码交互) 。
[root@pc205 ~]# useradd mike
[root@pc205 ~]# useradd nono
[root@pc205 ~]# echo 123456 | passwd --stdin mike
.. ..
[root@pc205 ~]# echo 123456 | passwd --stdin nono
.. ..
2)为客户机的用户mike、nono分别建立SSH密钥对
以用户mike登入客户机,使用ssh-keygen创建密钥对,设置好私钥口令:
[root@pc205 ~]# su - mike
[mike@pc205 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/mike/.ssh/id_rsa):
Created directory '/home/mike/.ssh'.
Enter passphrase (empty for no passphrase): //设置私钥口令
Enter same passphrase again: //再次输入私钥口令
Your identification has been saved in /home/mike/.ssh/id_rsa.
Your public key has been saved in /home/mike/.ssh/id_rsa.pub.
The key fingerprint is:
63:6e:cf:45:f0:56:e2:89:6f:62:64:5a:5e:fd:68:d2 mike@pc205.tarena.com
The key's randomart image is:
+--[ RSA 2048]----+
| |
| |
| . . . |
| = = |
| S = B . |
| o B = . o |
| + + = E .|
| . + + o |
| o |
+-----------------+
[mike@pc205 ~]$ ls -lh ~/.ssh/id_rsa* //确认密钥对文件
-rw-------. 1 mike mike 1.8K 8月 15 10:35 /home/mike/.ssh/id_rsa
-rw-r--r--. 1 mike mike 403 8月 15 10:35 /home/mike/.ssh/id_rsa.pub
[mike@pc205 ~]$ exit
Logout
切换到用户nono,使用ssh-keygen创建密钥对,将私钥口令设为空(直接回车):
[root@pc205 ~]# su - nono
[nono@pc205 ~]$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/nono/.ssh/id_rsa):
Created directory '/home/nono/.ssh'.
Enter passphrase (empty for no passphrase): //直接回车将口令设为空
Enter same passphrase again: //再次回车确认
Your identification has been saved in /home/nono/.ssh/id_rsa.
Your public key has been saved in /home/nono/.ssh/id_rsa.pub.
The key fingerprint is:
43:16:c1:88:5a:02:ec:d5:37:22:4e:c0:25:6f:84:63 nono@pc205.tarena.com
The key's randomart image is:
+--[ RSA 2048]----+
|+++o.. oo. |
| E=+oo.o.. |
|o =*. o + |
| .o. o |
| S |
| . |
| |
| |
| |
+-----------------+
[nono@pc205 ~]$ ls -lh ~/.ssh/id_rsa* //确认密钥对文件
-rw-------. 1 nono nono 1.7K 8月 15 10:37 /home/nono/.ssh/id_rsa
-rw-r--r--. 1 nono nono 403 8月 15 10:37 /home/nono/.ssh/id_rsa.pub
3)将客户机上用户mike、nono的公钥部署到SSH服务器
以用户nono登入客户机,使用ssh-copy-id命令将自己的公钥部署到服务器,服务器上的目标用户为john:
[nono@pc205 ~]$ ssh-copy-id john@192.168.4.7
john@192.168.4.7's password:
Now try logging into the machine, with "ssh 'john@192.168.4.7'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
[nono@pc205 ~]$ exit
Logout
同样地,以用户mike登入客户机,使用ssh-copy-id命令将自己的公钥部署到服务器,服务器上的目标用户也是john:
[root@pc205 ~]# su - mike
[mike@pc205 ~]$ ssh-copy-id john@192.168.4.7
john@192.168.4.7's password:
Now try logging into the machine, with "ssh 'john@192.168.4.7'", and check in:
.ssh/authorized_keys
to make sure we haven't added extra keys that you weren't expecting.
4)在服务器上确认客户机用户mike、nono上传的公钥信息
默认部署位置为目标用户de ~/.ssh/authorized_keys文件:
[root@svr7 ~]# tail -2 ~john/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAzz+5AiFMGQ7LfuiV7eBnOcmRO9JRTcqRoynGO2y5
RyFL+LxR1IpEbkNrUyIZDk5uaX1Y8rwsf+pa7UZ2NyqmUEvNSUo0hQyDGsU9SPyAdzRCCvDgwpOFhaHi/OFnT+zqjAqXH2M9fFYEVUU4PIVL8HT19zCQRVZ/q3acQA34UsQUR0PpLJAobsf1BLe2EDM8BsSHckDGsNoDT9vk+u3e83RaehBMuy1cVEN5sLAaIrIeyM8Q0WxQNlqknL908HRkTlTeKrRoHbMnOBFj8StwlnscKHlkrsKkhUf8A9WWz/vL4GDwGND5jdca3I2hdITAySjMdfL1HMHnMYOgMjPM0Q== nono@pc205.tarena.com
ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAl6PopFT7VoFaQFVVKrH4N7VgDIUUjcIc/TN/dmA1
EmTAqv9wYnX83Do3/14wUD6WkUQ1wkZV64bkHCrgUDsCy2iV7wvH7xiOg4CYGFk1RALn5edKC8fEKiveR8MrUafa6O2iBpuG/vYin2QDyc7PpipyRw4rFg7/PaD1XuRRwFGcHgiv8PLUjO6GcuS4c3gyKbSADM7mV1gu62wMHm47e5jAxzxNGkYnyYeb7Ut7hwvs5xP54MHy23zSs+DjN7oRvKN5xZueaFLbVUcnSvGzN5IZqV7Qu3NqtFGpgCdUr/yaFcZWC7VIrNH2IJJwKNboCMSUoEm+InRtIvITdCWWVQ== mike@pc205.tarena.com
5)在客户机上测试SSH密钥对验证
在客户机用户mike的环境中,以远程用户john登入192.168.4.7主机,需要验证客户机用户mike 的私钥口令:
[mike@pc205 ~]$ ssh john@192.168.4.7 //需验证私钥口令
Enter passphrase for key '/home/mike/.ssh/id_rsa':
Last login: Thu Aug 15 10:10:37 2013 from 192.168.4.207
[john@svr7 ~]$ whoami
john
而在客户机用户nono的环境中,以远程用户john登入192.168.4.7主机时,无需验证口令即可登入(因为私钥口令为空):
[nono@pc205 ~]$ ssh john@192.168.4.7 //免交互直接登入
Last login: Thu Aug 15 10:48:09 2013 from 192.168.4.207
[john@svr7 ~]$ whoami
john
步骤四:确认密钥验证使用正常后,禁用口令验证
1)调整sshd服务配置,将PasswordAuthentication设为no
[root@svr7 ~]# vim /etc/ssh/sshd_config
.. ..
PasswordAuthentication no //将此行yes改成no
[root@svr7 ~]# service sshd reload
重新载入 sshd: [确定]
2)确认密码登录验证已不可用,只有部署了公钥的用户才可以登录
[root@pc205 ~]# su - mike
[mike@pc205 ~]$ ssh zengye@192.168.4.7 //口令验证被拒绝
Permission denied (publickey,gssapi-keyex,gssapi-with-mic).
[mike@pc205 ~]$ ssh john@192.168.4.7 //密钥验证登录成功
Enter passphrase for key '/home/mike/.ssh/id_rsa':
Last login: Thu Aug 15 10:49:13 2013 from 192.168.4.207
Security基础(一):Linux基本防护措施、使用sudo分配管理权限、提高SSH服务安全的更多相关文章
- 三、使用sudo分配管理权限
使用sudo分配管理权限 su命令 su - [账户名称] :切换到用户,不加用户名默认切换到root su - [账户名称] -c '命令' :以xx用户身份执行命令,注意命令需 ...
- useradd和groupadd(Linux创建用户\用户组\设置\分配用户权限\多用户远程登录权限)的使用
前言: man useradd man groupadd info useradd info groupadd 都可以获取相关命令的用法信息. 个人比较喜欢读英文解释文档,没有你想象的那么comp ...
- linux基本防护措施,权限分配和提高防护安全
设置用户失效 1.失效的用户将无法登录 使用chage命令将用户zhangsan的账户设为当前已失效(比如已经过去的某个时间): [root@proxy ~]# useradd zhangsan [r ...
- 启动ssh服务 XSshell 生成秘钥 并注册公钥在Ubuntu linux
安装ssh服务:sudo apt-get install openssh-server 查看ssh服务: ps -ef | grep ssh 查看之后正常显示如下3行:root 8 ...
- SLAM+语音机器人DIY系列:(一)Linux基础——3.Linux命令行基础操作
摘要 由于机器人SLAM.自动导航.语音交互这一系列算法都在机器人操作系统ROS中有很好的支持,所以后续的章节中都会使用ROS来组织构建代码:而ROS又是安装在Linux发行版ubuntu系统之上的, ...
- Linux系统管理员命令:sudo
sudo是个统管一切的命令.它的字面意思是代表“超级用户才能做!”(super user do!)对Linux系统管理员或高级用户而言,它是必不可少的最重要的命令之一.你可曾有过这样的经历:在终端中试 ...
- 零基础学习Linux所必备的七大习惯
对于很多Linux初学者来说,在刚开始使用linux系统时会感到很多的不适.这里为大家整理了自己以前linux入门时别人告诉我的七个习惯.我相信如果你运用了这七个习惯,在你使用Linux时你会感觉更安 ...
- Linux系统实战项目——sudo日志审计
Linux系统实战项目——sudo日志审计 由于企业内部权限管理启用了sudo权限管理,但是还是有一定的风险因素,毕竟运维.开发等各个人员技术水平.操作习惯都不相同,也会因一时失误造成误操作,从而 ...
- 快速学习C语言三: 开发环境, VIM配置, TCP基础,Linux开发基础,Socket开发基础
上次学了一些C开发相关的工具,这次再配置一下VIM,让开发过程更爽一些. 另外再学一些linux下网络开发的基础,好多人学C也是为了做网络开发. 开发环境 首先得有个Linux环境,有时候家里机器是W ...
随机推荐
- 牛客多校训练营第九场 J - Symmetrical Painting (排序)
J - Symmetrical Painting 题意 给你\(n\)个矩形, 左下角\((i-1,\ L_i)\), 右上角\((i,\ R_i)\), 找一条线\(l\)平行于\(x\)轴, 让这 ...
- excel 中相乘函数
excel 中相乘函数 “PRODUCT”并且是公式的框框,格式要是 常规,不能是文本
- C#正则表达式将html代码中的所有img标签提取
/// <summary> /// 取得HTML中所有图片的 URL. /// </summary> /// <param name="sHtmlText&qu ...
- BZOJ 4484: [Jsoi2015]最小表示(拓扑排序+bitset)
传送门 解题思路 \(bitset\)维护连通性,给每个点开个\(bitset\),第\(i\)位为\(1\)则表示与第\(i\)位联通.算答案时显然要枚举每条边,而枚举边的顺序需要贪心,一个点先到达 ...
- 建站手册-浏览器信息:Google Chrome 浏览器
ylbtech-建站手册-浏览器信息:Google Chrome 浏览器 1.返回顶部 1. http://www.w3school.com.cn/browsers/browsers_chrome.a ...
- 利用单臂路由实现VLAN间路由(有1个疑问)
配置PC机: PC1:IP 192.168.1.1 :掩码:255.255.255.0:网关:192.168.1.254 VLAN 10 PC2:IP 192.168.2.1 :掩码:255.255 ...
- Java空对象模式
在“空对象”模式中,空对象将替换NULL对象实例的检查.而不是检查一个空值,Null对象反映一个无关的关系(即什么也不做). 这种Null对象还可以用于在数据不可用时提供默认行为. 在空对象模式(Nu ...
- Codefores 507C Guess Your Way Out!(递归)
C. Guess Your Way Out! time limit per test 1 second memory limit per test 256 megabytes input standa ...
- Android中shape的使用方法总结
<?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http ...
- Linux上用sublime编辑Python时候出现"SyntaxError: Non-ASCII character ‘\xe5′ in file"的问题
Reopen with Encoding UTF-8也没用,那只是在编辑界面里面显示出中文而已,编译的时候还是不能识别中文. 所以,还是按网上说的吧,在每一个有中文的文件第一行加上# -*- codi ...