生成AWS一键登录链接

生成一键登录AWS控制台的链接

第一步:保存登录密钥

echo '
[default]
aws_access_key_id = id
aws_secret_access_key = key
' > ~/.aws/credentials

第二步:编写代码

use Aws\Sts\StsClient;
use Aws\Exception\AwsException;

try {

    // https://docs.aws.amazon.com/aws-sdk-php/v3/download/aws.phar
    require 'aws.phar';

    $client = new StsClient(['version' => 'latest', 'region' => 'ap-northeast-1', 'profile' => 'default']);
    $policy = '{"Version": "2012-10-17", "Statement": [{"Effect": "Allow", "Action": "*", "Resource": "*"}]}';
    $token = $client->getFederationToken(['Name' => 'admin', 'Policy' => $policy]);
    $credentials = $token['Credentials'];
    $session = ['sessionId' => $credentials['AccessKeyId'], 'sessionKey' => $credentials['SecretAccessKey'], 'sessionToken' => $credentials['SessionToken']];
    $sign = json_decode(file_get_contents('https://signin.aws.amazon.com/federation?Action=getSigninToken&SessionDuration=1800&Session=' . urlencode(json_encode($session))), true);
    echo $loginUrl = 'https://signin.aws.amazon.com/federation?Action=login&Issuer=admin&Destination=https%3A%2F%2Fconsole.aws.amazon.com%2F&SigninToken=' . $sign['SigninToken'];
} catch (AwsException $e) {
    error_log($e->getMessage());
}
发布日期:
分类:php

k3s运行apisix控制台

首先创建控制台资源

apiVersion: apps/v1
kind: Deployment
metadata:
  name: apisix-dashboard
  namespace: apisix
  labels:
    app: apisix-server
spec:
  replicas: 1
  selector:
    matchLabels:
      app: apisix-server
  strategy:
    type: Recreate
  template:
    metadata:
      labels:
        app: apisix-server
    spec:
      containers:
        - name: apisix-server
          image: docker.io/apache/apisix-dashboard:2.9.0
          imagePullPolicy: Always
          volumeMounts:
            - mountPath: /usr/local/apisix-dashboard/conf/conf.yaml
              name: volume
          ports:
            - name: http
              containerPort: 9000
      volumes:
        - name: volume
          hostPath:
            path: /www/docker/apisix-dashboard/conf.yaml
            type: File

然后创建控制台服务

apiVersion: v1
kind: Service
metadata:
  name: dashboard-service
  namespace: apisix
spec:
  type: NodePort 
  selector:
    app: apisix-server
  ports:
  - port: 9000
    targetPort: 9000
    nodePort: 30083

对外暴露的端口就是 30083

发布日期:
分类:Linux

Docker多阶段构建

使用多阶段构建 Nginx

#### 第一阶段

# 基础镜像
FROM centos AS Nginx-Pre

# 添加远程文件到当前文件夹
ADD http://nginx.org/download/nginx-1.20.1.tar.gz /usr/local/src/

# 在镜像内运行解压命令
RUN tar zxvf /usr/local/src/nginx-1.20.1.tar.gz -C /usr/local/src/

# 切换目录
WORKDIR /usr/local/src/nginx-1.20.1

# 安装必要的软件
RUN yum install -y gcc gcc-c++ glibc make openssl-devel gd-devel pcre pcre-devel libxslt libxslt-devel

# 编译安装
RUN ./configure --prefix=/usr/local/nginx --with-file-aio --with-http_ssl_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module --with-http_image_filter_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_degradation_module --with-http_stub_status_module && make && make install

#### 第二阶段

# 基础镜像
FROM centos

# 复制软件包
COPY --from=Nginx-Pre /usr/local/nginx /usr/local/

# 执行启动命令
CMD ["-g", "daemon off;"]
发布日期:
分类:Linux

搭建Aria2服务端

  1. 安装
yum install -y aria2

2. 配置开机启动

# /etc/systemd/system/aria2.service
[Unit]
Description=aria2
After=network.target

[Service]
Type=simple
ExecStart=/usr/local/bin/aria2c --conf-path=/usr/local/aria2/aria2.conf
User=www
Group=www

[Install]
WantedBy=network.target

3. 启用服务

systemctl enable aria2
systemctl start aria2
发布日期:
分类:Linux

Go生成RSA密钥对

golang 原生库生成RSA密钥对,公钥和私钥保存为文件

package main

import (
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"os"
)

func generateRSAKey(privateFile, publicFile string, bits int) error {
	// 生成 RSA 私钥对象
	privateKey, err := rsa.GenerateKey(rand.Reader, bits)
	if err != nil {
		return err
	}

	// 通过x509标准将得到的ras私钥序列化为 ASN.1 的 DER 编码字符串
	x509PrivateKey := x509.MarshalPKCS1PrivateKey(privateKey)

	// 新建私钥文件
	private, err := os.Create(privateFile)
	if err != nil {
		return err
	}
	defer private.Close()

	// 将数据保存到文件
	err = pem.Encode(private, &pem.Block{
		Type:    "RSA Private Key",
		Headers: map[string]string{},
		Bytes:   x509PrivateKey,
	})
	if err != nil {
		return err
	}

	// X509对公钥编码
	X509PublicKey, err := x509.MarshalPKIXPublicKey(&privateKey.PublicKey)
	if err != nil {
		return err
	}

	// 新建公钥文件
	public, err := os.Create(publicFile)
	if err != nil {
		return err
	}
	defer public.Close()

	// 将数据保存到文件
	err = pem.Encode(public, &pem.Block{
		Type:    "RSA Public Key",
		Headers: map[string]string{},
		Bytes:   X509PublicKey,
	})
	if err != nil {
		return err
	}

	return nil
}

func main() {
	generateRSAKey("./private.key", "./public.key", 4096)
}
发布日期:
分类:Golang

Nginx 定时重启

利用 Linux 系统的 Crontab 定时任务管理 Nginx 重启

mkdir ~/crontab
echo "#!/bin/bash

/usr/local/nginx/sbin/nginx -t

if [ $? = "0" ]
then
    /usr/local/nginx/sbin/nginx -s reload
fi
" > ~/crontab/nginx_reload.sh

添加定时任务,每天凌晨定时重启

# nginx reload
00 00 *  *  *    /bin/sh ~/crontab/nginx_reload.sh > /tmp/nginx_reload.log 2>&1
发布日期:
分类:Linux

Gin 使用方法

  1. 基础用法:
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	r := gin.Default()

	r.GET("/", func(c *gin.Context) {
		c.String(200, "Index")
	})

	r.GET("/user/:name", func(c *gin.Context) {
		name := c.Param("name")
		c.String(http.StatusOK, "Hello %s", name)
	})

	r.POST("/form", func(c *gin.Context) {
		username := c.PostForm("username")
		password := c.DefaultPostForm("password", "000000")

		c.JSON(http.StatusOK, gin.H{
			"username": username,
			"password": password,
		})
	})

	r.POST("/upload", func(c *gin.Context) {
		file, _ := c.FormFile("file")
		// c.SaveUploadedFile(file, dst)
		c.String(http.StatusOK, "%s uploaded!", file.Filename)
	})

	r.Run("0.0.0.0:8800")
}

2. 常用方法

// c.Abort() 
// c.AbortWithError(code int, err error) *Error 
// c.AbortWithStatus(code int) 
// c.AbortWithStatusJSON(code int, jsonObj interface}) 
// c.AsciiJSON(code int, obj interface}) 
// c.Bind(obj interface}) error 
// c.BindHeader(obj interface}) error 
// c.BindJSON(obj interface}) error 
// c.BindQuery(obj interface}) error 
// c.BindUri(obj interface}) error 
// c.BindXML(obj interface}) error 
// c.BindYAML(obj interface}) error 
// c.ClientIP() string 
// c.ContentType() string 
// c.Cookie(name string) (string, error) 
// c.Data(code int, contentType string, data []byte) 
// c.DataFromReader(code int, contentLength int64, contentType string, reader io.Reader, extraHeaders map[string]string) 
// c.Deadline() (deadline time.Time, ok bool) 
// c.DefaultPostForm(key, defaultValue string) string 
// c.DefaultQuery(key, defaultValue string) string 
// c.Done() <-chan struct} 
// c.Err() error 
// c.Error(err error) *Error 
// c.File(filepath string) 
// c.FileAttachment(filepath, filename string) 
// c.FileFromFS(filepath string, fs http.FileSystem) 
// c.FormFile(name string) (*multipart.FileHeader, error) 
// c.FullPath() string 
// c.func bodyAllowedForStatus(status int) bool 
// c.func validateHeader(header string) (clientIP string, valid bool) 
// c.Get(key string) (value interface}, exists bool) 
// c.get(m map[string][]string, key string) (map[string]string, bool) 
// c.GetBool(key string) (b bool) 
// c.GetDuration(key string) (d time.Duration) 
// c.GetFloat64(key string) (f64 float64) 
// c.GetHeader(key string) string 
// c.GetInt(key string) (i int) 
// c.GetInt64(key string) (i64 int64) 
// c.GetPostForm(key string) (string, bool) 
// c.GetPostFormArray(key string) ([]string, bool) 
// c.GetPostFormMap(key string) (map[string]string, bool) 
// c.GetQuery(key string) (string, bool) 
// c.GetQueryArray(key string) ([]string, bool) 
// c.GetQueryMap(key string) (map[string]string, bool) 
// c.GetRawData() ([]byte, error) 
// c.GetString(key string) (s string) 
// c.GetStringMap(key string) (sm map[string]interface}) 
// c.GetStringMapString(key string) (sms map[string]string) 
// c.GetStringMapStringSlice(key string) (smss map[string][]string) 
// c.GetStringSlice(key string) (ss []string) 
// c.GetTime(key string) (t time.Time) 
// c.GetUint(key string) (ui uint) 
// c.GetUint64(key string) (ui64 uint64) 
// c.Handler() HandlerFunc 
// c.HandlerName() string 
// c.HandlerNames() []string 
// c.Header(key, value string) 
// c.HTML(code int, name string, obj interface}) 
// c.IndentedJSON(code int, obj interface}) 
// c.initFormCache() 
// c.initQueryCache() 
// c.IsAborted() bool 
// c.IsWebsocket() bool 
// c.JSON(code int, obj interface}) 
// c.JSONP(code int, obj interface}) 
// c.MultipartForm() (*multipart.Form, error) 
// c.MustBindWith(obj interface}, b binding.Binding) error 
// c.MustGet(key string) interface} 
// c.Negotiate(code int, config Negotiate) 
// c.NegotiateFormat(offered ...string) string 
// c.Next() 
// c.Param(key string) string 
// c.PostForm(key string) string 
// c.PostFormArray(key string) []string 
// c.PostFormMap(key string) map[string]string 
// c.ProtoBuf(code int, obj interface}) 
// c.PureJSON(code int, obj interface}) 
// c.Query(key string) string 
// c.QueryArray(key string) []string 
// c.QueryMap(key string) map[string]string 
// c.Redirect(code int, location string) 
// c.RemoteIP() (net.IP, bool) 
// c.Render(code int, r render.Render) 
// c.requestHeader(key string) string 
// c.SaveUploadedFile(file *multipart.FileHeader, dst string) error 
// c.SecureJSON(code int, obj interface}) 
// c.Set(key string, value interface}) 
// c.SetAccepted(formats ...string) 
// c.SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool) 
// c.SetSameSite(samesite http.SameSite) 
// c.ShouldBind(obj interface}) error 
// c.ShouldBindBodyWith(obj interface}, bb binding.BindingBody) (err error) 
// c.ShouldBindHeader(obj interface}) error 
// c.ShouldBindJSON(obj interface}) error 
// c.ShouldBindQuery(obj interface}) error 
// c.ShouldBindUri(obj interface}) error 
// c.ShouldBindWith(obj interface}, b binding.Binding) error 
// c.ShouldBindXML(obj interface}) error 
// c.ShouldBindYAML(obj interface}) error 
// c.SSEvent(name string, message interface}) 
// c.Status(code int) 
// c.Stream(step func(w io.Writer) bool) bool 
// c.String(code int, format string, values ...interface}) 
// c.Value(key interface}) interface} 
// c.XML(code int, obj interface}) 
// c.YAML(code int, obj interface}) 
发布日期:
分类:Golang

Golang网络函数

抓取网页内容

func getHtmlContent(u string, r string) []string {
	resp, err := http.Get(u)
	if err != nil {
		log.Println(err.Error())
		return nil
	}
	defer resp.Body.Close()

	if resp.StatusCode == http.StatusOK {
		c, err := ioutil.ReadAll(resp.Body)
		if err != nil {
			log.Println(err.Error())
			return nil
		}

		return regexp.MustCompile(`href=".*"`).FindAllString(string(c), -1)
	} else {
		log.Println("Error HTML Code: ", resp.StatusCode)
		return nil
	}
}
发布日期:
分类:Golang

树莓派编译安装PHP7.4

首先安装依赖

apt install -y libxml2 libxml2-dev libjpeg-dev libcurl4-openssl-dev libreadline-dev libzip-dev libfreetype6-dev libssl-dev libsqlite3-dev libonig-dev

下载源码并编译安装

wget https://www.php.net/distributions/php-7.4.15.tar.gz
tar zxf php-7.4.15.tar.gz
cd php-7.4.15

./configure \
--prefix=/usr/local/php \
--with-curl --with-freetype --with-gettext --with-iconv-dir --with-jpeg --with-libdir=lib64 --with-openssl --with-pear --with-readline --with-xmlrpc --with-zip --with-zlib \
--with-mysqli=mysqlnd --with-pdo-mysql=mysqlnd \
--enable-bcmath --enable-calendar --enable-exif --enable-fpm --enable-ftp --enable-gd --enable-intl --enable-mbstring --enable-mysqlnd --enable-pcntl \
--enable-soap --enable-sockets
make -j8 && make install

配置文件

cp php.ini-production /usr/local/php/lib/php.ini
sed -i 's/post_max_size = 8M/post_max_size = 50M/g' /usr/local/php/lib/php.ini
sed -i 's/upload_max_filesize = 2M/upload_max_filesize = 50M/g' /usr/local/php/lib/php.ini
sed -i 's/;date.timezone =/date.timezone = PRC/g' /usr/local/php/lib/php.ini
sed -i 's/expose_php = On/expose_php = Off/g' /usr/local/php/lib/php.ini