Loading... 在局域网环境中,为了保障数据传输的安全性并满足某些技术对HTTPS的需求,搭建一套可信任的SSL证书并实现全HTTPS访问是十分必要的。本文将基于实际操作经验,详细介绍如何在局域网内创建并部署可信任的SSL证书,确保浏览器能够安全地访问内网服务。 <!--more--> # 一、为什么需要内网SSL证书 在开发环境中,自签名证书虽然能满足基本需求,但在生产环境中,浏览器会提示证书不可信,用户需要手动点击“继续访问”,这对于自动化项目来说是不可接受的。此外,某些服务仅在HTTPS环境下工作。因此,为了实现自动化和满足技术需求,必须在局域网内搭建可信任的SSL证书。 2.开始制作证书 这里我使用的证书工具是openssl,经典工具,坦白的说非常难用。 # 二、创建CA证书 首先第一步,制作一个机构证书也就是CA证书出来,使用openssl创建CA证书。 ## 1.通过openssl创建CA证书 第一步是创建一个秘钥,这个便是CA证书的根本,之后所有的东西都来自这个秘钥: 通过rsa算法生成2048位长度的秘钥 `openssl genrsa -out myCA.key 2048` 第二步是通过秘钥加密机构信息形成公钥: - 公钥包含了机构信息,在输入下面的指令之后会有一系列的信息输入,这些信息便是机构信息,公司名称地址什么的 - 这里还有一个过期信息,CA证书也会过期,openssl默认是一个月,我们直接搞到100年 `openssl req -utf8 -new -x509 -key myCA.key -out myCA.cer -days 36500` 这一步需要输入的机构信息有点,分别说一下: - Country Name:国家代码,比如中国就是CN - State or Province Name:省名称 - Locality Name:城市名称 - Organization Name:机构名称 - Organizational Unit Name:机构单位名称 - Common Name:重点参数:授权给什么,因为机构是根节点所以是授权给自己 - Email Address:邮件地址 ## 2.创建服务器证书 在得到CA证书之后,需要通过openssl工具对证书进行转换得到公钥(.crt文件)和密钥(.key文件),无论CA证书是怎么来的到这里之后就没有任何区别了,服务器证书的制作流程相较CA证书要复杂一点点。 第一步通过openssl工具创建服务器的秘钥: - 通过RSA算法生成长度2048位的秘钥 `openssl genrsa -out server.key 2048` 第二步这里是创建一个签名请求 需要将服务器信息写入到请求文件之中,然后通过CA机构证书对请求签名形成服务器证书公钥,这一步要复杂一些,很多网上的教程在这里都GG了主要原因没有把原理搞清楚。 首先https证书的公钥不同于自定义情况下的加密证书,这里需要安装浏览器标准进行配置,首先openssl默认的证书版本是V1,V1在支持https时部分浏览器依旧会认为不安全,所以需要使用V3版本;同时openssl即便是使用V3版本依旧没有附带V3的subjectAltName字段数据(这里是证书对应的IP地址或者域名,可以用通配符)。但是这些东西命令行没法指定所以需要配置文件,参考一下配置: ``` HOME = . # Use this in order to automatically load providers. openssl_conf = openssl_init # Comment out the next line to ignore configuration errors config_diagnostics = 1 # Extra OBJECT IDENTIFIER info: # oid_file = $ENV::HOME/.oid oid_section = new_oids # To use this configuration file with the "-extfile" option of the # "openssl x509" utility, name here the section containing the # X.509v3 extensions to use: # extensions = # (Alternatively, use a configuration file that has only # X.509v3 extensions in its main [= default] section.) [ new_oids ] # We can add new OIDs in here for use by 'ca', 'req' and 'ts'. # Add a simple OID like this: # testoid1=1.2.3.4 # Or use config file substitution like this: # testoid2=${testoid1}.5.6 # Policies used by the TSA examples. tsa_policy1 = 1.2.3.4.1 tsa_policy2 = 1.2.3.4.5.6 tsa_policy3 = 1.2.3.4.5.7 # For FIPS # Optionally include a file that is generated by the OpenSSL fipsinstall # application. This file contains configuration data required by the OpenSSL # fips provider. It contains a named section e.g. [fips_sect] which is # referenced from the [provider_sect] below. # Refer to the OpenSSL security policy for more information. # .include fipsmodule.cnf [openssl_init] providers = provider_sect # List of providers to load [provider_sect] default = default_sect # The fips section name should match the section name inside the # included fipsmodule.cnf. # fips = fips_sect # If no providers are activated explicitly, the default one is activated implicitly. # See man 7 OSSL_PROVIDER-default for more details. # # If you add a section explicitly activating any other provider(s), you most # probably need to explicitly activate the default provider, otherwise it # becomes unavailable in openssl. As a consequence applications depending on # OpenSSL may not work correctly which could lead to significant system # problems including inability to remotely access the system. [default_sect] # activate = 1 #################################################################### [ ca ] default_ca = CA_default # The default ca section #################################################################### [ CA_default ] dir = ./demoCA # Where everything is kept certs = $dir/certs # Where the issued certs are kept crl_dir = $dir/crl # Where the issued crl are kept database = $dir/index.txt # database index file. #unique_subject = no # Set to 'no' to allow creation of # several certs with same subject. new_certs_dir = $dir/newcerts # default place for new certs. certificate = $dir/cacert.pem # The CA certificate serial = $dir/serial # The current serial number crlnumber = $dir/crlnumber # the current crl number # must be commented out to leave a V1 CRL crl = $dir/crl.pem # The current CRL private_key = $dir/private/cakey.pem # The private key x509_extensions = usr_cert # The extensions to add to the cert # Comment out the following two lines for the "traditional" # (and highly broken) format. name_opt = ca_default # Subject Name options cert_opt = ca_default # Certificate field options # Extension copying option: use with caution. # copy_extensions = copy # Extensions to add to a CRL. Note: Netscape communicator chokes on V2 CRLs # so this is commented out by default to leave a V1 CRL. # crlnumber must also be commented out to leave a V1 CRL. # crl_extensions = crl_ext default_days = 365 # how long to certify for default_crl_days= 30 # how long before next CRL default_md = default # use public key default MD preserve = no # keep passed DN ordering # A few difference way of specifying how similar the request should look # For type CA, the listed attributes must be the same, and the optional # and supplied fields are just that :-) policy = policy_match # For the CA policy [ policy_match ] countryName = match stateOrProvinceName = match organizationName = match organizationalUnitName = optional commonName = supplied emailAddress = optional # For the 'anything' policy # At this point in time, you must list all acceptable 'object' # types. [ policy_anything ] countryName = optional stateOrProvinceName = optional localityName = optional organizationName = optional organizationalUnitName = optional commonName = supplied emailAddress = optional #################################################################### [ req ] default_bits = 2048 default_keyfile = privkey.pem distinguished_name = req_distinguished_name attributes = req_attributes x509_extensions = v3_ca # The extensions to add to the self signed cert # Passwords for private keys if not present they will be prompted for # input_password = secret # output_password = secret # This sets a mask for permitted string types. There are several options. # default: PrintableString, T61String, BMPString. # pkix : PrintableString, BMPString (PKIX recommendation before 2004) # utf8only: only UTF8Strings (PKIX recommendation after 2004). # nombstr : PrintableString, T61String (no BMPStrings or UTF8Strings). # MASK:XXXX a literal mask value. # WARNING: ancient versions of Netscape crash on BMPStrings or UTF8Strings. string_mask = utf8only # req_extensions = v3_req # The extensions to add to a certificate request [ req_distinguished_name ] countryName = Country Name (2 letter code) countryName_default = AU countryName_min = 2 countryName_max = 2 stateOrProvinceName = State or Province Name (full name) stateOrProvinceName_default = Some-State localityName = Locality Name (eg, city) 0.organizationName = Organization Name (eg, company) 0.organizationName_default = Internet Widgits Pty Ltd # we can do this but it is not needed normally :-) #1.organizationName = Second Organization Name (eg, company) #1.organizationName_default = World Wide Web Pty Ltd organizationalUnitName = Organizational Unit Name (eg, section) #organizationalUnitName_default = commonName = Common Name (e.g. server FQDN or YOUR name) commonName_max = 64 emailAddress = Email Address emailAddress_max = 64 # SET-ex3 = SET extension number 3 [ req_attributes ] challengePassword = A challenge password challengePassword_min = 4 challengePassword_max = 20 unstructuredName = An optional company name [ usr_cert ] # These extensions are added when 'ca' signs a request. # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy # This is required for TSA certificates. # extendedKeyUsage = critical,timeStamping [ v3_req ] # Extensions to add to a certificate request basicConstraints = CA:FALSE keyUsage = nonRepudiation, digitalSignature, keyEncipherment subjectAltName = @alt_names # 这里是重点,需要将里面配置为最终服务端需要的域名或者IP # 这里可以写多个,能够自行添加DNS.X = XXXXXX [ alt_names ] DNS.1 = example.com DNS.2 = *.example.com IP.1 = 192.168.31.2 IP.2 = 192.168.31.3 [ v3_ca ] # Extensions for a typical CA # PKIX recommendation. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid:always,issuer basicConstraints = critical,CA:true # Key usage: this is typical for a CA certificate. However since it will # prevent it being used as an test self-signed certificate it is best # left out by default. # keyUsage = cRLSign, keyCertSign # Include email address in subject alt name: another PKIX recommendation # subjectAltName=email:copy # Copy issuer details # issuerAltName=issuer:copy # DER hex encoding of an extension: beware experts only! # obj=DER:02:03 # Where 'obj' is a standard or added object # You can even override a supported extension: # basicConstraints= critical, DER:30:03:01:01:FF [ crl_ext ] # CRL extensions. # Only issuerAltName and authorityKeyIdentifier make any sense in a CRL. # issuerAltName=issuer:copy authorityKeyIdentifier=keyid:always [ proxy_cert_ext ] # These extensions should be added when creating a proxy certificate # This goes against PKIX guidelines but some CAs do it and some software # requires this to avoid interpreting an end user certificate as a CA. basicConstraints=CA:FALSE # This is typical in keyUsage for a client certificate. # keyUsage = nonRepudiation, digitalSignature, keyEncipherment # PKIX recommendations harmless if included in all certificates. subjectKeyIdentifier=hash authorityKeyIdentifier=keyid,issuer # This stuff is for subjectAltName and issuerAltname. # Import the email address. # subjectAltName=email:copy # An alternative to produce certificates that aren't # deprecated according to PKIX. # subjectAltName=email:move # Copy subject details # issuerAltName=issuer:copy # This really needs to be in place for it to be a proxy certificate. proxyCertInfo=critical,language:id-ppl-anyLanguage,pathlen:3,policy:foo #################################################################### [ tsa ] default_tsa = tsa_config1 # the default TSA section [ tsa_config1 ] # These are used by the TSA reply generation only. dir = ./demoCA # TSA root directory serial = $dir/tsaserial # The current serial number (mandatory) crypto_device = builtin # OpenSSL engine to use for signing signer_cert = $dir/tsacert.pem # The TSA signing certificate # (optional) certs = $dir/cacert.pem # Certificate chain to include in reply # (optional) signer_key = $dir/private/tsakey.pem # The TSA private key (optional) signer_digest = sha256 # Signing digest to use. (Optional) default_policy = tsa_policy1 # Policy if request did not specify it # (optional) other_policies = tsa_policy2, tsa_policy3 # acceptable policies (optional) digests = sha1, sha256, sha384, sha512 # Acceptable message digests (mandatory) accuracy = secs:1, millisecs:500, microsecs:100 # (optional) clock_precision_digits = 0 # number of digits after dot. (optional) ordering = yes # Is ordering defined for timestamps? # (optional, default: no) tsa_name = yes # Must the TSA name be included in the reply? # (optional, default: no) ess_cert_id_chain = no # Must the ESS cert id chain be included? # (optional, default: no) ess_cert_id_alg = sha256 # algorithm to compute certificate # identifier (optional, default: sha256) [insta] # CMP using Insta Demo CA # Message transfer server = pki.certificate.fi:8700 # proxy = # set this as far as needed, e.g., http://192.168.1.1:8080 # tls_use = 0 path = pkix/ # Server authentication recipient = "/C=FI/O=Insta Demo/CN=Insta Demo CA" # or set srvcert or issuer ignore_keyusage = 1 # quirk needed to accept Insta CA cert not including digitalsignature unprotected_errors = 1 # quirk needed to accept negative responses possibly not protected extracertsout = insta.extracerts.pem # Client authentication ref = 3078 # user identification secret = pass:insta # can be used for both client and server side # Generic message options cmd = ir # default operation, can be overridden on cmd line with, e.g., kur # Certificate enrollment subject = "/CN=openssl-cmp-test" newkey = insta.priv.pem out_trusted = apps/insta.ca.crt # does not include keyUsage digitalSignature certout = insta.cert.pem [pbm] # Password-based protection for Insta CA # Server and client authentication ref = $insta::ref # 3078 secret = $insta::secret # pass:insta [signature] # Signature-based protection for Insta CA # Server authentication trusted = $insta::out_trusted # apps/insta.ca.crt # Client authentication secret = # disable PBM key = $insta::newkey # insta.priv.pem cert = $insta::certout # insta.cert.pem [ir] cmd = ir [cr] cmd = cr [kur] # Certificate update cmd = kur oldcert = $insta::certout # insta.cert.pem [rr] # Certificate revocation cmd = rr oldcert = $insta::certout # insta.cert.pem ``` 将上面的配置内容保存为openssl.cnf放到生成的服务器证书文件的目录下(注意:修改alt_names里面的域名或者IP为最终部署需要的地址,支持通配符),然后执行创建签名申请文件即可,执行运行: - 和创建CA时一样这里需要输入一堆服务器信息,输入项也是相同的。 - 不过在输入Common Name(CN)最好直接输入服务器的IP地址或者域名。 `openssl req -utf8 -config openssl.cnf -new -out server.req -key server.key` 第三步通过CA机构证书对服务器证书进行签名认证 将签名请求文件进行签名最终得到服务器的公钥 `openssl x509 -req -extfile openssl.cnf -extensions v3_req -in server.req -out server.cer -CAkey myCA.key -CA myCA.cer -sha384 -days 36500 -CAcreateserial -CAserial serial` # 三、客户端信任配置 为了确保客户端浏览器信任内网的HTTPS服务,需要将根证书安装到客户端的信任列表中。 - 如果使用Windows域控,可以通过组策略将根证书推送到域内的所有客户端。 - 对于非域控环境,需要手动将根证书导入到客户端的信任根证书颁发机构中。 # 四、测试访问 在局域网内的客户端浏览器中访问配置了SSL证书的服务地址,检查是否能够正常访问且浏览器显示为安全连接(如绿色的小锁图标)。如果显示为不安全连接,可能是因为客户端未正确安装根证书,需要重新检查根证书的导入情况。 # 五、总结 通过上述步骤,你可以在局域网内创建可信任的SSL证书,并实现全HTTPS访问。这不仅可以提升内网服务的安全性,还能为用户提供更可靠的访问体验。在实际操作中,建议根据具体的服务器和客户端环境进行适当调整,确保整个过程的顺利进行。 希望这篇文章能为你在局域网内搭建可信任的SSL证书提供清晰的指导。如果你在实施过程中遇到任何问题,欢迎随时交流讨论。 参考文章:[局域网内搭建浏览器可信任的SSL证书](https://www.tangyuecan.com/2021/12/17/%e5%b1%80%e5%9f%9f%e7%bd%91%e5%86%85%e6%90%ad%e5%bb%ba%e6%b5%8f%e8%a7%88%e5%99%a8%e5%8f%af%e4%bf%a1%e4%bb%bb%e7%9a%84ssl%e8%af%81%e4%b9%a6/) 最后修改:2025 年 03 月 23 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏