PowerShell脚本中密码加密保存

在做自动化的时候会使用到PowerShell脚本,有时候会有远程连接其他服务器的场景,例如连接VMware vCenter Server,出于安全考虑,不建议将密码明文的方式保存在脚本中,可以使用SecureString的方式加密保存。

SecureString 是 .net 中的一个类型,它是为了解决安全性而设计出来的一种特殊的字符串类型。比如你使用一个密码字符串创建 SecureString 对象,你无法通过这个对象还原出原来的密码字符串,但是却可以把 SecureString 对象当做密码使用。
Encrypted Standard String 是指经过加密后的一个字符串。

ConvertTo-SecureString命令可以通过明文的字符串创建SecureString对象:

$SecurePwd = ConvertTo-SecureString "password" -AsPlainText -Force

接下来通过ConvertFrom-SecureString,我们可以把一个SecureString对象转换成Encrypted Standard String。在创建Credential的时候使用生成的Encrypted Standard String,从而避免密码以明文的方式保存在系统中。

那我们在脚本中如何使用这一长串的经过转换的字符串呢?还是使用ConvertTo-SecureString。参照如下脚本:

$SecurePwd = ConvertTo-SecureString "password" -AsPlainText -Force
ConvertFrom-SecureString $SecurePwd
01000000d08c9ddf0115d1118c7a00c04fc297eb010000007e60d35c88a6754d97d685911ef7ce3a000000000200000000001066000000010000200000004f64c1c377a3d41cd7f5126ee11de07ade363c1fe75a7046e19f1c3564c2616a000000000e8000000002000020000000d89d6a13999fdae8f3aa94a3391e4577e7007a23058df3dd775baef097a5721d200000009f319764aaa0333a6ebbb535794d9193c02195bb710922bccb223cb4482fe48b40000000bf4e33bad709c942feeafdc5a1f3b254c17b3274212caa5219857f2621252d75f5e983bbf9afc92430cc120a2d585ab73b45943ea8c87e696039a70601d90fbd
$encryptedText = "01000000d08c9ddf0115d1118c7a00c04fc297eb010000007e60d35c88a6754d97d685911ef7ce3a000000000200000000001066000000010000200000004f64c1c377a3d41cd7f5126ee11de07ade363c1fe75a7046e19f1c3564c2616a000000000e8000000002000020000000d89d6a13999fdae8f3aa94a3391e4577e7007a23058df3dd775baef097a5721d200000009f319764aaa0333a6ebbb535794d9193c02195bb710922bccb223cb4482fe48b40000000bf4e33bad709c942feeafdc5a1f3b254c17b3274212caa5219857f2621252d75f5e983bbf9afc92430cc120a2d585ab73b45943ea8c87e696039a70601d90fbd"
$encryptedPassword = $encryptedText | ConvertTo-SecureString
$cred = New-Object -TypeName System.Management.Automation.PSCredential("JustGiveAName", $encryptedPassword)
$username = "admin"
$password = $cred.GetNetworkCredential().Password

这样在脚本中使用用户名和密码的时候就直接调用$username和$password变量啦。

但是使用这种方法还是有一个限制,就是生成的那一长串字符自能在当前机器上使用,如果复制到其他机器上使用,就会在执行ConvertTo-SecureString时报错。这是一种安全限制,如果需要在其他机器使用,需要采用新的办法,使用一个Key文件来生成这个加密后的长字符串。

ConvertTo-SecureSting和ConvertFrom-SecureString命令都支持选项-key。在处理密码时通过Key选项可以提供额外的安全性以及在多台机器上使用加密后密码的能力:

首先生成32位的Key文件,并保存在AES.key文件中:

$keyFile = "D:\aes.key"
$key = New-Object Byte[] 32
[Security.Cryptography.RNGCryptoServiceProvider]::Create().GetBytes($key)
$key | out-file $keyFile

使用key生成加密后的密码字符串:

$SecurePwd = ConvertTo-SecureString "password" -AsPlainText -Force
ConvertFrom-SecureString $SecurePwd -key $key
76492d1116743f0423413b16050a5345MgB8AGcAcQBKADkANgBvAGIAdQAxAGIAMQA1ADgAZQAzADUAVQBTADIAcwBIAEEAPQA9AHwAZQAxAGYAOAAyAGEAZQA4ADUAMABjADcANwA2ADAAYwAwAGMAOQBjAGIAYQBiAGQAYgBiAGIAMQAwADIAMgA3ADgAMQA3ADcANABhADkAZABjADQAOAA5AGMAZQBhADcAZQA2AGYAMQBmADkAMwBlADIANgA2ADEANwA2ADIAOAA=
$encryptedText = "76492d1116743f0423413b16050a5345MgB8AGcAcQBKADkANgBvAGIAdQAxAGIAMQA1ADgAZQAzADUAVQBTADIAcwBIAEEAPQA9AHwAZQAxAGYAOAAyAGEAZQA4ADUAMABjADcANwA2ADAAYwAwAGMAOQBjAGIAYQBiAGQAYgBiAGIAMQAwADIAMgA3ADgAMQA3ADcANABhADkAZABjADQAOAA5AGMAZQBhADcAZQA2AGYAMQBmADkAMwBlADIANgA2ADEANwA2ADIAOAA="
$keyFile = "D:\aes.key"
$key = Get-Content $keyFile
$username = "admin"
$Cred = New-Object -TypeName System.Management.Automation.PSCredential `
          -ArgumentList $username, ($encryptedText | ConvertTo-SecureString -Key $key)
$password = $cred.GetNetworkCredential().Password

发表在 Powershell | 留下评论

Kubernetes dashboard安装

初学K8S,自己搭了个K8S集群,具体怎么搭的都忘记了,没啥困难的,主要是得科学上网从k8s.gcr.io上pull image,这篇文章不讨论怎么搭K8S集群,主要描述我怎么搭建K8S的dashboard。

既然是K8S的dashboard,那必然也是基于容器的。下面的链接可以自己先查查兼容性,确认需要安装哪个版本的dashboard。

https://github.com/kubernetes/dashboard/releases

首先下载dashboard的yaml文件:

wget https://raw.githubusercontent.com/kubernetes/dashboard/master/aio/deploy/recommended/kubernetes-dashboard.yaml

下载到本地后,先别急着部署容器,使用文本编辑器查找image,看看dashboard需要pull那些image:

containers:
- name: kubernetes-dashboard
image: k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1

上述可以看出,需要k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1这个image,需要科学上网pull下来。

如果k8s集群的各个节点不方便科学上网,例如我现在做测试的环境,那可以曲线救国:

1、找一台能访问k8s.gcr.io的服务器,docker pull k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1。

2、将image push到docker hub上:

$ docker login 
$ docker tag k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1 your_docker_account/kubernetes-dashboard-amd64:v1.10.1
$ docker push your_docker_account/kubernetes-dashboard-amd64:v1.10.1

3、在本地的k8s集群的每个节点上从docker hub上pull dashboard image。

$ docker login
$ docker pull your_docker_account/kubernetes-dashboard-amd64:v1.10.1
$ docker tag your_docker_account/kubernetes-dashboard-amd64:v1.10.1 k8s.gcr.io/kubernetes-dashboard-amd64:v1.10.1
$ docker rmi your_docker_account/kubernetes-dashboard-amd64:v1.10.1

下载完镜像,先别急着部署容器,还得修改一下dashboard的yaml文件。K8S集群基于RBAC方式访问,我们需要对账号做授权,这里我直接修改了kubernetes-dashboard-minimal账号的权限(正确的方法应该是新建一个账号,然后赋予相关权限)。修改kubernetes-dashboard.yaml文件,修改 kubernetes-dashboard-minimal的属性改为如下内容:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: kubernetes-dashboard-minimal
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: kubernetes-dashboard
namespace: kube-system

这里再附录一下如何新建账号并赋予cluster admin的权限:

apiVersion: v1
kind: ServiceAccount
metadata:
name: admin-user
namespace: kube-system


apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: admin-user
namespace: kube-system
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: cluster-admin
subjects:
- kind: ServiceAccount
name: admin-user
namespace: kube-system

接下来就可以部署dashboard容器了:

$ kubectl create -f kubernetes-dashboard.yaml
$ kubectl get svc -n kube-system

使用浏览器访问dashboard。K8S dashboard提供了四种方位的方式:Proxy、NodePort、API Server和Ingress,详细介绍可参考如下链接:

https://github.com/kubernetes/dashboard/wiki/Accessing-Dashboard—1.7.X-and-above

这里主要讨论Proxy和NodePort:

1、Proxy方式访问。运行如下命令开启本地代理:

$ kubectl proxy
Starting to serve on 127.0.0.1:8001

开启浏览器,输入一下URL访问dashboard:

http://localhost:8001/api/v1/namespaces/kube-system/services/https:kubernetes-dashboard:/proxy/

2、NodePort方式访问。编辑kubernetes-dashboard服务,修改service为NodePort方式:

$ kubectl -n kube-system edit service kubernetes-dashboard

修改type为NodePort:

apiVersion: v1
kind: Service
metadata:
creationTimestamp: 2019-03-05T09:21:22Z
labels:
k8s-app: kubernetes-dashboard
name: kubernetes-dashboard
namespace: kube-system
resourceVersion: "12362875"
selfLink: /api/v1/namespaces/kube-system/services/kubernetes-dashboard
uid: 0b11a598-3f28-11e9-8c7c-00155d0c2307
spec:
clusterIP: 10.101.237.197
externalTrafficPolicy: Cluster
ports:
- nodePort: 39033
port: 443
protocol: TCP
targetPort: 8443
selector:
k8s-app: kubernetes-dashboard
sessionAffinity: None
type: NodePort
status:
loadBalancer: {}

检查host端dashboard service expose的端口:

$ kubectl get svc -n kube-system 
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
kube-dns ClusterIP 10.96.0.10 53/UDP,53/TCP 126d
kubernetes-dashboard NodePort 10.101.237.197 443:39033/TCP 21h
tiller-deploy ClusterIP 10.111.108.186 44134/TCP 58d

在浏览器中输入地址: https://<master-ip>:39033 访问dashboard。

接下来我们在浏览器中能看到登录界面:

有两种方式登录,一个是Kubeconfig文件,一个是令牌,这里我们使用令牌登录。记得我们最开始修改 kubernetes-dashboard.yaml 文件,为kubernetes-dashboard用户赋予集群管理的权限,现在我们需要拿到 kubernetes-dashboard 的token:

$ kubectl -n kube-system get secrets |grep kubernetes-dashboard
kubernetes-dashboard-certs Opaque 0 21h
kubernetes-dashboard-csrf Opaque 1 21h
kubernetes-dashboard-key-holder Opaque 2 22h
kubernetes-dashboard-token-t5ksp kubernetes.io/service-account-token 3 21h
$ kubectl -n kube-system describe secret kubernetes-dashboard-token-t5ks

复制token到浏览器中,点击登录,这样就登录到K8S的dashboard啦!


发表在 docker | 留下评论

WordPress站点的SSL连接

接上篇,我们已经使用自己申请的域名和云主机搭建好了基于Wordpress的个人站点,接下来我们再稍加改造,让我们的站点支持SSL连接。

向腾讯云申请使用期为1年的免费的SSL证书,并将证书下载到本地,证书提供商为TrustAsia。

官方的wordpress镜像默认是没有开启SSL的,需要执行a2enmod ssl命令开启SSL。但是如果使用docker exec进入到容器开启会遇到个问题,那就是每次容器重启时我们都得再进入到容器执行这条命令。为了避免这个问题,我们可以重新打包wordpress image,将执行这条命令的语句加入到image中。

新建文件Dockerfile,加入如下内容:

FROM wordpress   
RUN a2enmod ssl  
ENTRYPOINT ["docker-entrypoint.sh", "apache2-foreground"]

重新构建wordpress iamge:

docker build -t wordpress:v1 .    

复制正在运行的wordpress容器中的/etc/apache2文件夹中的所有文件到宿主机并停止正在运行的wordpress容器。

docker cp wordpress:/etc/apache2 /home/hui/wordpress/.   
docker stop wordpress
docker rm wordpress

配置Apache2的SSL/HTTPS

cd /home/hui/wordpress/apache2/   
cp sites-available/000-default.conf ./sites-enabled/
cp sites-available/default-ssl.conf ./sites-enabled/.
cd mods-enabled/
ln -s ../mods-available/socache_shmcb.load ./

将腾讯云上申请的SSL证书上传到服务器/home/hui/wordpress/apache2/sites-available目录下。

编辑/home/hui/wordpress/apache2/sites-enabled/default-ssl.conf文件,设置如下变量:

SSLCertificateFile        /etc/apache2/sites-available/2_www.gaohui.xyz.crt   
SSLCertificateKeyFile   /etc/apache2/sites-available/3_www.gaohui.xyz.key
SSLCertificateChainFile  /etc/apache2/sites-available/1_root_bundle.crt

编辑/home/hui/wordpress/apache2/sites-enabled/000-default.conf文件,强制跳转到HTTPS,增加如下内容:

ServerName www.gaohui.xyz       
ServerAdmin webmaster@localhost
DocumentRoot /var/www/html
<Directory "/var/www/html">
RewriteEngine   on
RewriteBase /
# FORCE HTTPS
RewriteCond %{HTTPS} !=on
RewriteRule ^/?(.*) https://%{SERVER_NAME}/$1 [R,L]
</Directory>

重新运行wordpress容器:

docker run --name wordpress -d -p 80:80 -p 443:443 --link mysql -v    /home/hui/wordpress/app:/var/www/html -v    /home/hui/wordpress/apache2:/etc/apache2 -e WORDPRESS_DB_HOST=mysql:3306  wordpress:v1    

进入wordpress配置页面,安装插件“Easy HTTPS (SSL) Redirection”和”Really Simple SSL”。

设置站点的地址, 点击设置,修改下图中的地址:

发表在 docker | 留下评论

使用wordpress搭建个人站点

1、腾讯云申请1元域名。

2、新建一台云主机,Ubuntu 16.04 LTS,并为云主机分配公网IP。

3、腾讯云上添加域名解析,解析IP为云主机的公网IP。

4、云主机上安装docker。

5、云主机上运行mysql容器:

docker run --name mysql -d -v /home/user/wordpress/mysql:/var/lib/mysql  -e MYSQL_ROOT_PASSWORD="123456" -e MYSQL_DATABASE=wordpress mysql:5.7 


6、云主机上运行wordpress容器:

docker run --name wordpress -d -p 80:80 --link mysql -v /home/user/wordpress/app:/var/www/html -e WORDPRESS_DB_HOST=mysql:3306 wordpress

7、浏览器中输入云主机IP,配置wordpress。

发表在 docker | 留下评论