3 加密和Web服务器配置
3.1 不同Web服务器的示例
网络软件程序(也称为Web服务器)向用户浏览器发送页面的性质近年来发生了巨大变化。2000年代主要由Apache软件[APA 16]和基于Microsoft的服务器互联网信息服务(IIS)[MIC 16]之间的竞争主导。尽管Apache服务器目前是最常用的服务器类型,但一种名为 NGINX [NGI 16],的新秀最近开始流行起来,以其卓越的性能而闻名。IIS已基本消失,除了一些特定平台外,很少被使用。
这些服务器的配置方式各不相同。Apache通过全局配置文件或直接放置在文件系统中的.htaccess文件来控制行为,而NGINX的工作方式则不同,每个应用程序(网站名称)都有一个单独的配置文件,通常保存在/etc/nginx/sites‐enabled文件夹中。这种方式使代码审查更加容易:您无需浏览整个目录树即可确定系统配置,但也存在缺点,尤其是在托管平台的环境中。由于可能无法访问该文件,因此并不总是能够指定所需的设置。
这些Web服务器都可以采用相同的配置,尽管实际操作命令可能有所不同。为每种服务器分别进行说明意义不大;我们仅以Apache为例进行说明,因为Apache是最常见的Web服务器,被几乎所有活跃网站的50%所使用[NET 16]。
3.2 加密概念简介
加密是指通过修改消息,使其对不知道密钥或解密方法的任何人来说都变得不可理解的过程。我们区分两种主要的加密类型:对称加密及其变体哈希,以及非对称加密。后者的实现基于数字证书。
3.2.1 对称加密
对称加密(或私钥加密)使用相同的密钥来加密和解密消息。密码算法被应用于正在加密的信息。该密码算法的一个参数是仅由发送方和接收方知晓的密钥(图3.1)。
给定密钥和密码算法,可以通过应用与该密钥相关的逆向密码算法来解密加密消息。
有两种技术可以实现这一点。分组密码将消息分成多个等长部分(根据算法不同,长度在64到256位之间)。这是计算机系统中最常见的加密类型。流密码逐位加密消息:这种技术主要用于无线电传输系统(例如GSM——手机网络、蓝牙——无线网络)。
密钥本身的大小通常在56到256位之间。
对称密码算法的强度取决于多个因素。密钥越长,加密越安全。普遍认为,256位的密钥(2^256约等于 10^77,),据估计接近该数量宇宙中的电子数量)无法通过暴力破解(即逐一测试每种组合)来破解。
然而,密钥长度并不是决定密码算法强度的唯一因素。消息是逐块加密的,每个块越大,密码算法就越强。同时,计算函数也会被多次应用(迭代次数)。迭代次数越多,密码算法越强;法国网络与信息安全局建议执行65,000次迭代。还必须考虑算法本身的适用性,并且密钥必须完全随机生成。
为了提高安全性,特别是对于代码或密码,限制允许的尝试次数也是一个好方法。例如,智能卡在三次尝试失败后会被锁定,这意味着只需4到6位数字的解锁码就已足够。
如今,最广泛使用的算法是AES256:块的大小为128位,密钥为256位。目前认为该算法是安全的。
对称加密由于其算法的简单性(矩阵置换和布尔异或类型),在计算时间上成本较低。
函数被应用于数据)。然而,它们存在一个缺点:发送方和接收方必须首先交换密钥。在互联网连接中,确认发送方和接收方的身份是困难的,并且密钥必须以一种其他人无法看到的方式进行传输。我们将在下文看到,非对称加密为这一问题提供了解决方案。
3.2.2 计算哈希值和密码加盐
在计算中,哈希是从文件或任意字符序列计算出的固定长度字符序列。该哈希是唯一的:不可能从不同的数据得到相同的哈希。但如果算法不够安全,或可能的组合数量过少,则可能发生碰撞,即两个不同的字符串可能导致相同的哈希1。最后,不应能够从哈希还原原始数据。
哈希在两种主要情况下非常有用。第一种情况是我们希望验证文件副本与原始文件是否完全相同,例如在下载ISO镜像时。提供下载的网站会标明哈希值,并说明用于计算该值的方法。文件下载完成后,可以轻松重新计算其哈希值,并核对两个值是否一致。如果存在差异,则说明下载的文件与原始文件不完全相同,可能是由于传输过程中的错误,或是受到黑客干扰,通常表现为中间人攻击 [WIK 15a]。在这种攻击中,攻击者将自己置于客户端计算机和Web服务器之间,并实时重写传输的信息。
哈希值还被用于以无法解码的方式对密码进行编码。
可以使用特殊程序来存储密码。创建密码时,会计算其哈希值,并将该哈希值存储在数据库中。验证密码时,程序会计算用户输入的字符串的哈希值,然后将其与数据库中存储的值进行比较。如果两个哈希值相同,则密码被视为正确(图3.2)。
如今,md5算法不再单独使用,主要就是由于这一弱点。
今天,我们将通过一种称为加盐的技术来扩展此过程。哈希是由提供给哈希算法的数据计算得出的。但如果这些数据是可预测的(例如密码过于简单),则可能相对容易地从哈希中恢复原始数据。
这在密码的实际使用中可能会发生。太多人选择了容易猜测的密码:例如字符串 password 或 12345678、名字或孩子及配偶的出生日期等,不幸的是,这些都是非常常见的选择。如果攻击者知道了哈希算法,并且在发生入侵或数据窃取后获得了数据库的访问权限,他们就能够运行搜索,轻松找到其中一些密码。
为了防范此类攻击的风险,一种解决方案是在计算哈希时加入一段可变信息。这种可变信息对每个用户都不同,这称为加盐。通常将账户或登录ID(必然是唯一的)附加到密码上:即使两个用户的密码相同,此过程也会产生不同的哈希值。以下是使用密码 password 和两个不同用户账户 john 与 mark 的示例(代码是通过 Linux命令 生成的):
echo john password |sha256sum 88071bcc…
我们将用户名(john)和密码(密码)连接在一起,然后计算哈希值。现在我们对另一个用户名 mark 执行相同的操作:
echo mark password |sha256sum bd6e27fb08…
这两个哈希值不同。
因此,即使密码本身相同,存储在数据库中的值也永远不会相同。即使攻击者知道了加盐算法,他们也不得不为每个账户重新计算所有可能的值,这使得他们的任务变得更加复杂。
3.2.3 非对称加密
对称加密足以保护通信安全,但它存在一个根本性缺陷:加密密钥必须在双方之间共享。因此,我们需要一种方法来交换密钥,同时防止密钥被截获,并验证与我们通信的一方的身份。
非对称加密为这一问题提供了解决方案。
非对称协议基于两个随机选择的素数生成两个密钥。这一过程的显著特性是,使用其中一个密钥加密的消息只能通过另一个密钥进行解密:
使用密钥1加密的消息只能用密钥2解密。反之亦然:使用密钥2加密的消息只能用密钥1解密。
实际上,第一个密钥由其所有者保密:它被称为私钥。第二个密钥,即公钥,则传输给所有请求它的接收方。
这种机制提供了一种简便的方法来完成两项不同的任务:加密消息和验证通信伙伴的身份。
如果鲍勃想向爱丽丝发送一条加密消息,他会获取她的公钥,并用它来加密消息。爱丽丝随后可以使用她的私钥解密该消息:她是唯一能够这样做的,因为只有她知道自己的私钥。
现在,如果爱丽丝向鲍勃发送一条消息,而鲍勃想要确定这条消息确实是由爱丽丝发送的,那么该过程就稍微复杂一些(图3.4)。
执行以下操作序列: – 爱丽丝使用上述讨论的哈希函数计算她消息的哈希值;– 她使用自己的私钥加密该哈希值;– 她将带有加密哈希的消息发送给鲍勃;– 鲍勃收到此消息后,计算其哈希值;– 他使用爱丽丝的公钥解密爱丽丝发送的加密哈希;– 最后,他比较两个哈希值:如果它们相同,则一定是爱丽丝发送了该消息。
当然,该协议是自动执行的,这些计算由软件程序完成,例如 Thunderbird[MOZ 15] 等电子邮件客户端。
非对称加密相对较为稳健,因为目前尚无法快速分解两个素数的乘积
目前,用于生成密钥的素数必须至少具有2048位的长度,以确保其安全性。即使在今天,法国网络与信息安全局也建议使用3096位的密钥,特别是那些计划在2030年之后继续使用的密钥。
3.2.4 加密密钥的理想长度是多少?
此处列出的数值取自ANSII[ANS 14]发布的文档。
以下是一些示例,用以说明所涉及的数量级。
| 2^n | 10^n | 数量级 |
|---|---|---|
| 2^32 | 4,294,967,296 | 地球人口数量 |
| 2^46 | 7.036874418 × 10^13 | 日地距离 ,以毫米为单位 |
| 2^55 | 1.237940039 × 10^27 | 3.602879702 × 10^16每秒十亿次(1GHz)速率下1年内执行的操作次数 |
| 2^90 | 1.157920892 × 10^77 | 每秒十亿次(1 GHz)的速率 |
| 2^256 | 1.157920892 × 10^77 | 每秒十亿次速率下150亿 年内执行的操作次数宇宙中电子的估计数量 |
对于秘密密钥加密(对称密钥),分组大小最小必须为64位( 2020年之后为128位)。加密密钥的长度必须至少为128位。普遍认为, 256位长度的密钥将永远不会被暴力破解所攻破。
非对称加密的解密规则完全不同:使用因式分解过程,其计算更为简便。生成密钥所用的素模数的最小尺寸不应小于2048位(对于计划在2030年后继续使用的证书,应不小于3072位)。
3.2.5 数字证书和证书链
使用非对称加密的一个问题在于,很难确定爱丽丝提供的公钥确实是她的,而没有被攻击者替换。
一种解决方案是信任一个认证机构,该机构可保证公钥的有效性。
认证机构使用以下步骤对爱丽丝的公钥进行签名:– 当爱丽丝生成她的两个密钥时,她会将她的公钥发送给认证机构;– 认证机构通过检查爱丽丝的身份证明文件等方式验证其身份,然后通过使用认证机构自身的私钥加密其哈希值来对其公钥进行签名。公钥和加密哈希存储在数字证书中。
为了验证数字证书(以及相应的公钥)确实属于爱丽丝,她的通信伙伴可以计算爱丽丝公钥的哈希值,然后使用认证机构的公钥解密该加密哈希。如果这两个哈希值相同,只要用户信任认证机构,就可以确信该密钥属于爱丽丝。这与上述消息签名的过程完全相同(参见第3.2.3 节)。
证书颁发机构的公钥直接内置于计算机系统中,这意味着它们可以被信任,而无需一定了解所有这些机构。软件发布商(如为Firefox浏览器提供支持的Mozilla基金会)负责包含由证书颁发机构签发的集成证书。这些公钥在技术上通过将其置于自签名证书中来实现,即由创建该密钥的认证机构直接签名的证书。
大多数情况下,证书颁发机构不会使用其私钥来生成客户端的证书,而是创建一个中间密钥,然后使用该中间密钥来生成所需的证书。这形成了一个证书链(图3.5)。
在此示例中,服务器证书由三级证书生成。为了使浏览器能够验证服务器提交的证书,服务器在请求时提供三张证书,从而可以追溯到已知的认证机构(根证书)。
证书可实现对人员或设备的可靠识别。因此,它们可用于在应用程序中验证用户身份、签署消息或文档,以及加密消息或通信,以防止未经授权的方读取。此过程用于Web应用程序,即HTTPS协议的形式(参见第3.4节)。
3.3 生成和管理加密证书
3.3.1 OpenSSL库
OpenSSL 是用于管理 TLS 加密的工具库。它在 Apache 许可证下发布,几乎可用于所有操作系统,是实际应用中最常用的库。
3.3.2 不同类型的证书
公钥、私钥和证书有多种格式,最常见的如下所示:– DER:用于编码用 ASN.1 编写的 x509 证书。标准文件扩展名:.der、.cer、.crt、.cert; – PEM:隐私增强邮件。这是带有ASCII头部的base64编码的DER。标准文件扩展名:.pem、.cer、.crt、.cert;– PKCS#12:个人信息交换语法标准。这是一种用于存储私钥、公钥和证书的标准,通常以密码保护的形式存在。数据以二进制形式存储。文件扩展名:.p12、.pfx(适用于微软)。
个人证书以 .p12 格式存储。它们同时包含私钥和公钥,因此应始终设置密码保护。
3.3.3 生成证书
证书是由认证机构签名的公钥。要创建证书,最佳方案是向公认的认证机构提交请求,但也可以通过创建自己的认证机构来自签名证书。在这种情况下,浏览器不会将该证书识别为安全的。
在我们的讨论中,我们将从签署自己的公钥开始。如果我们无法访问认证机构,这将是我们唯一的选择。
3.3.3.1 创建根证书
我们首先创建与根证书对应的权威私钥。
openssl req ‐new ‐x509 ‐keyout cacert.pem ‐out cacert.pem ‐ days 3650
此命令将生成一个私钥‐公钥密钥对。当执行该程序时,会提示输入密码:此密码用于保护私钥,在每次签署证书时都需要提供。此处,根证书的有效期为10年(3650天)。
cacert.pem 文件包含私钥和公钥。
我们现在将生成属于认证机构的证书,该证书将用于验证后续生成的其他证书;因此,此证书包含认证机构的公钥:
openssl x509 ‐in cacert . pem ‐ out cacert . crt
根证书是文件 cacert.crt。
3.3.3.2 创建服务器的私钥和公钥
现在我们将生成密钥对(私钥和公钥),例如用于Web服务器:
openssl genrsa ‐out 服务器 . 密钥2 2048
该密钥的长度为2048位。
我们可以保护它,以防止除根用户或授权进程以外的任何人访问它:
chmod 600 server .key
与有固定有效期的证书不同,私钥‐公钥对没有有效期。
3.3.3.3 创建由根机构验证的证书请求
使用我们刚刚生成的密钥对,我们将准备一个请求并提交给认证机构。该请求包含公钥,以及其他信息,包括我们要为其生成密钥的服务 器或网站的名称:
openssl req ‐new ‐key 服务器.密钥 ‐out 服务器.csr
运行此命令后,我们需要填写一些字段。要使某个字段为空,我们使用句点(.)。
国家名称(2字母代码)[AU ]:美国 州或省名称(全名)[ Some‐State ]:. 地区名称(例如,城市)[]:. 组织名称(例如,公司)[Internet Widgits Pty Ltd]:MY COMPANY 组织单位名称 (例如,部门)[]:. 通用名称(例如,您的名称)[]: myserver.company.com 电子邮件地址 []:.
请输入以下“额外”属性,以随您的证书请求一并发送: 挑战密码 []:可选公司名称[]:
最后两个字段留空。挑战密码用于生成解锁私钥的密码,在本示例中不需要。
请注意:通用名称必须与将要使用的服务器或网站的名称相匹配。在验证密钥时,软件会检查服务器或网站名称是否与此字段中存储的值完全相同。
一些证书颁发机构允许在此处指定多个名称,从而允许同一张证书用于多个DNS条目。这种做法有时用于邮件服务器,使其能够对TLS POP访问(pop.myserver.com)和网络邮件( webmail.myserver.com)等服务使用同一张证书。还可以创建包含通配符的证书,例如*.mydomain.com:该域名的所有子站点都可以通过同一张证书进行验证。然而,由于此类做法带来的风险,目前官方已不建议这样做:如果证书被劫持,单个组织的所有网站都可能被伪造。
也可以从同一个私钥‐公钥对创建多个证书:服务器托管的每个网址分别提交一个请求。
3.3.3.4 本地签署证书
如果您不想使用注册机构的服务,则需要自行生成证书。首次执行此操作时,您需要使用以下命令创建一个包含所生成证书的序列号( cacert.srl文件)以及证书本身的文件:
openssl x509 ‐req ‐in server.csr ‐CA cacert.pem ‐CAkey cacert.pem ‐out server.crt ‐C acreateserial
如果cacert.srl文件存在,则执行此操作的命令为:
openssl x509 ‐ req ‐days 3650 ‐in server.csr ‐CA cacert.pem ‐ out server.crt
server.crt 文件是一个证书,其中不仅包含公钥本身,还包含使用根证书加密的哈希值。
3.3.3.5 向注册机构申请证书签名
如果有认证机构,您可以将包含证书请求的文件(server.csr)发送给他们。作为回报,您将收到一份证书包含公钥及其加密哈希。通常,组织名称和组织单位名称字段是必填的:请咨询您的认证机构以了解哪些字段是必需的。
您还需要获取根证书(相当于 cacert.crt,即认证机构的公钥),这将使您能够验证证书的有效性。
3.3.3.6 不使用注册机构创建自签名证书
某些应用程序需要一个简单的自签名证书,即不由注册机构(甚至个人注册机构)签名的证书。在执行证书创建请求后,请运行以下命令:
openssl x509 ‐ req ‐ days 3650 ‐ in server . csr ‐ signkey server . key ‐ out server . crt
文件 server.crt 包含自签名证书。
3.3.4 密钥和证书存储在哪里?
在使用OpenSSL库的基于Linux的系统中,通常使用以下文件夹:– /etc/ssl/certs:包含证书和公钥。该文件夹可被所有设备用户读取。– /etc/ssl/私有:包含设备的私钥。
对此第二个文件夹的访问需要严格管理:如果有人获得了私钥,他们就可以解密所有加密消息,或冒充发送方。这种攻击被称为中间人[WIK 15a]。
默认情况下,只有root账户才能访问此文件夹,这会阻止Web服务器进程访问私钥,导致其无法发起HTTPS连接。
要更改此行为,我们需要允许 ssl‐证书 组浏览此文件夹,并为该组提供私钥的读取权限:
sudo chmod g+x ssl ‐ cert / etc / ssl / 私钥 sudo chmod g+r ssl ‐ cert / etc / ssl / 私钥 /\*
sudo 命令授予执行命令的管理权限。
现在,将Web服务器使用的账户(在本例中为www‐data)添加到 ssl‐证书组中:
sudo usermod ‐a ‐G ssl‐cert www‐data
重启Apache服务器后,它将能够访问私钥并正确管理HTTPS连接。
3 加密和Web服务器配置
3.3.5 查看密钥和证书的命令
查看私钥内容:
openssl rsa ‐in server . key ‐ text
私钥:(2048 位) 模数:
00:bb:6c:c9:c5:57:4f:f3:7c:83:56:a9:2d:c1:5d:(...) 公钥指数:
65537 (0x10001) 私钥指数:
07:d3:12:d9:5a:3b:cc:3e:76:7d:37:b2:e1:4f:b2:(...) 质数1:
00:e4:40:84:cf:08:d9:b5:c8:2e:74:a3:3f:75:72:(...) 指数1:
23:be:72:cd:d5:2d:fa:c8:a1:75:c4:86:d0:86:a1:(...) 系数:
58:c0:2b:ea:71:eb:a5:60:e0:a0:25:f5:7c:b1:94:(...)
75:53:08:da:ea:e1:74:6d 正在写入 RSA 私钥 ‐‐‐‐‐BEGIN RSA PRIVATE KEY‐‐‐‐‐
MIIEogIBAAKCAQEAu2zJxVdP83yDVqktwV0saR1QafKL+
XblgtQT8pHDx2XQCWdW(...)IK/QexnadKjz8jZT78nxL+
N1xqK5RSBaAsk/hzQsdVMI2urhdG0=‐‐‐‐‐END RSA PRIVATE KEY‐‐‐‐‐
查看关联的公钥:
openssl rsa ‐in server.key ‐pubout 正在写入 RSA 密钥 ‐‐‐‐‐BEGIN PUBLIC KEY‐‐‐‐‐ MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ(...) OwIDAQAB ‐‐‐‐‐END PUBLIC KEY‐‐‐‐‐
查看证书:
openssl x509 ‐in server.crt ‐text ‐noout 证书:数据:版本:1 (0x0) 序列号:16235780570068490813 (0xe15114685a1f1a3d) 签名算法: sha256WithRSAEncryption 颁发者:C=FR, CN=equinton 有效性 生效时间:Jun 22 15:35:19 2016 GMT 失效时间:Jun 20 15:35:19 2026 GMT 主题:C=FR, CN=equinton 主体公钥信息: 公钥算法:rsaEncryption 公钥:(2048 位) 模数: 00:bb:6c:c9:c5:57:4f:f3:7c:83:(...)
指数:65537 (0x10001) 签名算法: sha256WithRSAEncryption 23:29:ee:e1:6b:50:2c:d9:9e:6b:4c:10:2e:84:cc
(...)
检查证书的有效性:
openssl verify ‐CAfile cacert.crt 服务器.crt server .crt: 正常
3.4 实现HTTPS协议
3.4.1 理解HTTPS协议
如今,数字通信需要达到一定的机密性最低门槛(以保护密码、银行信息等)。HTTPS协议的原理是加密所有通信,该协议最初是 HTTP over SSL,现在是HTTP over TLS [WIK15h](SSL因不再被认为是安全的而被弃用)。
TLS 是一种基于对称密钥的加密方法,非常符合这一需求。它唯一的缺点是,像所有对称密钥协议一样,密钥必须在双方之间进行交换,且不能被截获。
为了实现这一点,设计者提出通过使用非对称加密来启动对话。图 3.6给出了该协议的略微简化的示意图。
假设浏览器希望通过HTTPS连接到Web服务器(通常Web服务器会将浏览器重定向到HTTPS协议,但结果相同)。浏览器会获取 Web服务器提供的证书,然后使用认证机构的公钥解密哈希以验证其有效性。如果证书未被识别,浏览器将显示警告消息,并要求用户确认后才能访问所请求的页面。
如果证书有效,浏览器会使用TLS协议生成一个对称密钥,然后使用服务器的公钥对其进行加密,并将其发送到服务器。
服务器检索密钥,然后使用其私钥进行解密:现在服务器和浏览器之间可以 confidentially 交换信息。
实际上,服务器在发送证书的同时还会发送其他信息,例如可接受的对称加密协议列表。
通过此流程,只有服务器需要验证其身份,且只有服务器需要提供数字证书。然而,某些HTTPS协议的实现也要求客户端提供证书。这尤其用于服务器之间的直接通信,以自动交换消息。
3.4.2 实现HTTPS协议
HTTPS协议依赖于数字证书。为了保护一个应用程序,您必须首先获取一个证书。该证书包含应用程序网址的准确名称,例如 my_application.com。这使得浏览器能够检查给定的证书是否与所请求网站的名称匹配。
证书还必须由公认的认证机构提供:否则,浏览器会提示无法验证该证书。这是因为如上所述的证书链(参见第3.2.5节)不完整。
下一步是确保Apache服务器将通过HTTP协议发送的所有请求重定向到HTTPS协议。这在虚拟主机配置文件中完成,该文件位于/ etc/apache2/sites‐available文件夹中。以下是一个示例配置:
<虚拟主机\*:80>
服务器名称 myapp . com
服务器路径 / myapp . com
重写引擎 开启
重写规则 ^ https :// myapp . com /%{ REQUEST _ URI }[R ]
</ 虚拟主机 >
现在,所有通过HTTP(即发送到80端口)传输的内容都将被重定向到HTTPS协议。为此,我们使用URL重写功能(Rewrite)。
现在我们将了解如何配置我们的应用程序以HTTPS模式进行访问:
<虚拟主机\*:443>
服务器名称 myapp.com
服务器路径 /myapp.com
服务器管理员 admin@myapp.com
服务器 签名 关闭
VirtualHost 命令现在指向用于 HTTPS 的端口443。我们还看到一些通用命令,其中之一显示了站点管理员的名称(一个通用地址)。ServerSignature Off 命令会隐藏 Apache 服务器的版本信息。
使用以下命令启用对HTTPS协议的支持:
SSLEngine on
SSLCertificateFile / etc/ssl/certs/myapp.cert
SSLCertificateKeyFile / etc/ssl/private/myapp.key
SSLCACertificateFile / etc/ssl/certs/cachain.pem
我们还可以看到证书的访问路径:SSLCertificateFile 是证书(已签名的公钥),SSLCertificateKeyFile 是私钥,SSLCACertificateFile 是包含证书链的文件,即签署该公钥的每个机构的公钥。
现在,我们必须使用以下命令指定应用程序代码的位置:
DocumentRoot /var/www/myappApp/myapp
最后,应用程序专用的日志文件:
CustomLog /var/log/apache2/myapp‐access.log combined
ErrorLog /var/log/apache2/myapp‐error.log
</VirtualHost >
所有访问信息都存储在文件 /var/log/apache2/myapp‐access.log 中( combined 指定了日志文件的格式选择),错误则记录在文件 / var/log/apache2/myapp‐error.log 中。
3.4.3 测试SSL证书链
证书成功添加且Apache配置完成后,检查加密是否正确配置是很有必要的。已配置。有多种工具可用于此目的,这些工具可以以可下载的形式用于测试内网的配置,也可以直接在线使用。对于后者,我们只需提供 Web服务器的地址,然后该网站会启动一个或多或少全面的分析,首先检查证书链,然后检查所使用的协议。SSLLABS [LAB 16]可能提供了最全面的工具之一。这使我们能够识别服务器可能仍在接受的任何过时协议,并提供一份兼容的操作系统和浏览器列表。
3.5 提高Apache服务器的安全性
在本节中,我们将简要讨论如何提高Apache Web服务器的安全性。这并非系统管理的详尽指南,而只是汇总了一些有用的准则:系统管理员可能已经了解所有这些内容,但或许仍会希望借助清单来确保没有遗漏任何事项。以下配置适用于运行 Ubuntu Server 14.04 LTS 的 Linux服务器。
3.5.1 确保托管Apache的服务器具有最新的安全更新
服务器首次安装时,通常已包含最新的安全补丁。然而,由于不断有新的漏洞被发现,服务器需要定期更新,一般至少每天一次。对于 Ubuntu 或 Debian 类型的发行版,我们可以使用无人值守升级包,该工具包专门设计用于自动化此过程。
此软件包使用 /etc/apt/apt.conf.d/50unattended‐upgrades 文件来指定用于配置更新软件的所有参数。可以用来指定以下内容,包括但不限于:– 应使用哪些仓库来执行更新。通常,对于服务器,我们只应安装安全性更新; – 是否存在不应更新的软件包:通常情况下,libc 库就是如此,因为它是系统正常运行所必需的;对该组件的任何更改都可能导致严重问题;
设备在需要时(通常是在安装新内核后)是否应重启。如果启用此选项,可以指定服务器重启的时间。自动重启可防范内核本身存在的漏洞,避免导致拒绝服务或权限提升攻击。然而,重启是一项复杂的操作,尤其是在服务器共享资源的虚拟环境中,因此建议事先确保该操作能够安全完成。
还有其他一些设置,例如发送电子邮件的设置,我们在此不再讨论。
3.5.2 禁止低安全性的协议
20世纪90年代,美国政府禁止将其境内的强安全性协议出口到境外。这导致人们使用安全性较低的协议。当时这并不是一个问题,但以当今可用的计算能力来看,这些协议已变得容易被绕过。
为了与现有网站保持兼容,Apache Web服务器继续允许所有类型的协议。不幸的是,即使使用了安全的证书,除非明确禁止, Apache仍会继续使用弱加密连接。
为此,我们必须编辑配置文件 / etc/apache2/sites‐available/default‐ssl,并在以 开头的部分中添加以下行:
SSL 协议 所有 ‐ SSLv2 ‐ SSLv3
SSL 遵循密码套件顺序 开启
SSL 密码套件 ECDHE‐RSA‐AES128‐SHA256:AES128‐GCM‐SHA256:HIGH:EECDH+ AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH:!MD5:! aNULL:!EDH:!RC4
SSL 压缩 关闭
第一行禁用了被认为已过时的 SSL 协议,转而强制使用 TLS。接下来的两行强制使用 SHA256 签名算法(默认为使用 128 位密钥的 SHA‐1),以及其它被认为可靠的新型协议。最后,最后一条命令禁用了 SSL 压缩,因为这可能会带来安全性问题(该指令通常默认设置为关闭)。
雷米·范·埃尔斯特在一篇相当全面的文章中进一步讨论了这些问题,该文章详细介绍了如何使用Apache2[ELS 15]全面保护SSL连接。
如今,有一些网站可以生成适应使用场景(Web服务器、支持的浏览器等)的配置。例如,Mozilla基金会提供的网站 [MOZ16b] 就非常全面。参考这些工具可以更容易地跟上加密技术的发展步伐。
3.5.3 防止请求洪泛
“关闭”服务器(即阻止其响应请求)的最简单方法之一,就是同时发送数以万计的请求。这被称为拒绝服务攻击。
Apache防逃避模块可应对此类攻击。它会阻止在给定时间单位内发送的相同请求,并限制同一用户在每个时间单位内的请求数量。
这个模块很容易安装:
sudo apt‐get install libapache2‐mod‐evasive
其参数可以在文件 /etc/apache2/mods‐available/evasive.conf 中进行配置。
以下是一些示例值(默认值显示在括号中): – DOSHashTableSize (3097):用于记录调用的表的大小; – DOSPageCount (2):同一用户在给定时间单位内调用的请求次数。通常默认值已足够,除非在同一页面内多次调用同一组件;– DOSSiteCount (50):在给定时间单位内对网站的调用次数,按所有页面累计; – DOSPageInterval (1):用于计算请求数量的时间间隔,单位为秒;
– DOSSiteInterval (1):用于计算所有传入请求的时间间隔; – DOSBlockingPeriod (10):被阻止的用户无法完成请求的时间段,单位为秒。
要使模块正常工作,必须在重启Apache服务器之前取消注释每个参数以激活它们。
使用默认参数值时,如果用户在1秒内向服务器发送两个相同请求,将被阻止10秒。如果用户每秒发送的请求超过50个,也会被阻止。
每当一个请求被阻止时,一条消息会被保存到错误日志文件 / var/log/apache2/error.log 中:
[Thu Jun 23 0 9 : 2 1 : 0 8 . 539066 2016][e v a s i v e 2 0 : 错误][ pid 19145][客户端::1:54188]服务器配置拒绝客户端访问: / var / www / html / eabxcol / display / images / logo . png , 来源: https :// l o c a lh o s t / eab xcol / index . php ? m o d u l e =m a n a g e m e n t
referer 指定了最初被调用的页面,即被阻止的页面。
该模块的优势在于,如果超过阈值,服务器将使用极少的资源:请求不会被完成,处理时间也会非常短。
它通常安装在反向代理服务器上,作为该组织关联的所有应用程序或网站的网关。由于它仍在服务器本身上执行,因此其防护效果仅限于一定程度:如果攻击规模真正巨大,服务器资源最终仍会被耗尽。可以实施其他更复杂的防护技术,但这需要对实际网络设备进行修改,甚至需要在互联网服务提供商(ISP)层面进行调整。
与其他防护措施一样,应首先考虑风险是否证明有必要在此模块之外实施其他措施。
3.5.4 实现请求过滤器
Apache 提出了一种名为 mod_security 的模块,用于分析服务器接收到的请求,并在必要时进行过滤,然后再将其转发给 PHP 引擎。
这被称为应用防火墙,它在实际连接到 Web 服务器之前充当接口。
此模块的配置可能较为复杂,但可提供基本配置的示例。
首先,需要在服务器上安装:
sudo apt‐get install libapache2‐mod‐security2
Apache服务器会自动重启,但该模块尚未运行:尚未定义任何指令。默认的根配置文件位于/etc/modsecurity文件夹中,需要重命名以便模块能够识别。
cd /etc/modsecurity && sudo cp modsecurity.conf‐recommended modsecurity.conf
您需要修改此文件的内容以适应您自己的配置。为了允许下载最大为64兆字节的文件,您需要修改以下指令:
SecRequestBodyLimit 67108864
我们现在将启用该模块使用的基本指令。输入以下命令:
for f in ‘ls /usr/share/modsecurity‐crs/base_rules/\*‘; do sudo ln ‐s $f; done
并重启Apache服务器:
sudo 服务 apache2 重启
默认情况下,该模块配置为仅记录异常事件(文件 modsecurity.conf 中的指令 SecRuleEngine DetectionOnly)。您可以测试程序是否能正确检测异常,例如在提交的字段中输入字符串; or 1= 1‐‐(此命令表示一次 SQL注入攻击(参见第4.2.1节))。系统将在日志文件 /etc/apache2/modsec_audit.log 中创建一条记录。
检查日志文件,并通过删除其链接来禁用任何您不想使用的模块。
DigitalOcean[DIG 提供了编写非常出色的英文文档。您还可以访问官方项目网站 [MOD 15]。
在生产服务器上启用此模块之前,应先进行测试。特别要检查其生成的日志文件(它们可能会迅速变得很大),并且仅启用您实际需要的模块。
如果您的应用程序已正确编码并得到安全保护,且已在Apache中直接采取了基本预防措施,那么此模块对您来说可能并非必要。然而,对于从网络获取的开源应用程序,它可能非常有价值。例如,几年前编写的会议室预订软件可能并未包含针对SQL注入等最常见攻击类型的最新防护措施。与其重写或花费时间修改其代码以确保安全性,更有效的方法可能是将其部署在如modsecurity之类的应用防火墙之后。如果该防火墙配置得当,将能够阻止大多数常见的攻击类型。
当然,此方法仅应用于低优先级应用程序,且仅在攻击成功时风险有限的情况下使用。
3.5.5 允许页面头修改
现代浏览器现在能够实施多种不同的安全检查,前提是服务器要求启用这些检查。由于在某些情况下它们可能会导致应用程序无法正常工作,因此默认情况下这些检查是禁用的。
这些检查旨在限制通过精心设计的脚本窃取其他网页的 Cookie 的风险JavaScript。要让浏览器实施这些预防措施,需要将它们包含在Web服务器发送的HTML头部中。
为了允许应用程序修改HTML头部,我们首先需要使用以下命令加载一个模块来补充Apache:
a2enmod headers
service apache2 重启
接下来,我们将了解应使用哪些指令来增强应用程序的保护。
3.5.6 授权.htaccess文件
.htaccess文件允许我们修改Apache服务器在各个文件夹中的行为。这主要用于防止访问关键文件夹,例如包含数据库连接信息的文件夹。
由于这些文件包含特殊指令,我们必须要求 Apache 允许执行它们。
通常,当在服务器上安装新应用程序时,会使用一个配置文件在 / etc/apache2/sites‐available 文件夹中注册一个新的虚拟站点。该文件指定了应用程序在服务器中的物理位置,并设置了各种参数,例如用于HTTPS连接的加密证书。我们需要确保该文件包含以下指令:
<目录 / myfolder >
允许覆盖 all
Order allow , deny
allow from all
</ 目录 >
第一条指令AllowOverride允许覆盖文件夹/myfolder中的所有 Apache指令,以确保正确读取应用程序的所有.htaccess文件。
3.5.7 隐藏 Apache 和 PHP 的版本信息
允许攻击者查看已安装软件的版本会向他们提供有价值的信息,特别是当所有软件未完全更新时。如果我们使用的PHP版本已过时且已知容易受到某种特定攻击,暴露版本号将让攻击者确切地知道如何渗透系统。
通过在Firefox浏览器中安装wappAlyzer [WAP 15]模块,可以轻松检查Web应用程序是否显示其版本号。该模块会收集有关应用程序和服务器所有组件的信息:操作系统、Web引擎、语言以及所有第三方软件组件(如JQuery [JQU 15])。如果版本号未被隐藏,该模块将显示这些版本号。
为了防止Apache服务器及其PHP模块泄露版本号,我们只需编辑配置文件即可。对于Apache,需要编辑文件/ etc/apache2/conf.d/security,并检查以下参数的配置:
ServerTokens Prod
ServerSignature Off
可以通过修改 /etc/php5/apache2/php.ini 文件中的以下参数来配置 PHP:
expose_php=关闭
必须重启 Apache 才能使这些更改生效。
3.6 总结
应用程序永远不能被视为本质上是安全的:其运行时环境在整体安全性中起着重要作用。
如今,加密对于保护应用程序至关重要。仅允许在HTTPS模式下访问是必要的第一步,但还不够:还必须正确配置Web服务器以禁用过时的协议。
设置 Apache 防逃避模式或应用防火墙等措施可以增强应用程序的安全性,前提是这些措施配置正确。将应用程序部署到生产环境需要系统管理员和开发人员之间的密切协作。必须兼顾双方的需求,以实现性能与保护之间的良好平衡。
1093

被折叠的 条评论
为什么被折叠?



