0%

密码复杂度校验

MySQL5.6.6版本之后增加了密码强度验证插件validate_password.

-- 查看插件是否安装
mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS  WHERE PLUGIN_NAME LIKE 'validate_password';
+-------------------+---------------+
| PLUGIN_NAME       | PLUGIN_STATUS |
+-------------------+---------------+
| validate_password | ACTIVE        |
+-------------------+---------------+
1 row in set

-- 如果没有安装
INSTALL PLUGIN validate_password SONAME 'validate_password.so';

-- 卸载
UNINSTALL PLUGIN validate_password;
-- 查看密码校验相关参数
mysql> show  variables like '%validate_password%';
+--------------------------------------+--------+
| Variable_name                        | Value  |
+--------------------------------------+--------+
| validate_password_check_user_name    | OFF    |
| validate_password_dictionary_file    |        |
| validate_password_length             | 8      |
| validate_password_mixed_case_count   | 1      |
| validate_password_number_count       | 1      |
| validate_password_policy             | MEDIUM |
| validate_password_special_char_count | 1      |
+--------------------------------------+--------+
参数名 说明
validate_password_check_user_name 用户名检测,设置为ON的时候表示能将密码设置成当前用户名
validate_password_dictionary_file 字典文件
validate_password_length 密码的长度要求
validate_password_mixed_case_count 密码中至少有1个大写小字母
validate_password_number_count 密码中至少1个数字
validate_password_policy 密码的安全策略,参数可选值:MEDIUMLOWSTRONG. LOW:策略仅测试密码长度。MEDIUM:策略添加了密码必须至少包含数字、大小写和特殊字符的条件。STRONG:策略除了MEDIUM外,还不能匹配字典文件中的字词.
validate_password_special_char_count 密码中至少1个特殊字符
-- 密码规范测试,评分达到100才能使用
select VALIDATE_PASSWORD_STRENGTH('123456');

-- 另一种方法测试
mysql> select password('1234');
mysql> select password('1234#Qsss');
+-------------------------------------------+
| password('1234#Qsss')                     |
+-------------------------------------------+
| *F7BE83BBADD1FA159B1028170433FE7CBA5C0D01 |
+-------------------------------------------+
1 row in set

字典文件的使用:

  1. 设置策略为STRONG
set global validate_password_policy=STRONG;
  1. 创建字典文件
[root@ ~]# cat /tmp/validate_password_dictionary_file 
admin 
root 
love 
password 
  1. 配置字典文件路径
-- 配置
mysql> set global validate_password_dictionary_file="/tmp/validate_password_dictionary_file"; 
Query OK, 0 rows affected (0.00 sec) 
-- 查看
mysql> SHOW STATUS LIKE 'validate%'; 

MySQL 5.7.8之前,服务器运行时对字典文件的更改需要重新启动才能使服务器识别更改; 而在5.7.9后可动态设置并生效

密码过期

[mysqld]
# 设置默认过期时间,单位天,默认永不过期0
default_password_lifetime=90
# 默认ON,密码过期会断开连接
disconnect_on_expired_password=ON
-- 运行时修改, 重启失效
SET GLOBAL default_password_lifetime = 90;
-- 针对特定用户设置过期策略
ALTER USER 'user'@'localhost' PASSWORD EXPIRE;
ALTER USER 'user'@'localhost' PASSWORD EXPIRE INTERVAL 30 DAY;
ALTER USER 'user'@'localhost' PASSWORD EXPIRE NEVER;
ALTER USER 'user'@'localhost' PASSWORD EXPIRE DEFAULT;

账户锁定

-- 5.7.8版本之后,新增锁定账户功能
CREATE USER 'furrywall'@'localhost' IDENTIFIED BY '71m32ch4n6317' ACCOUNT LOCK;
ALTER USER 'furrywall'@'localhost' ACCOUNT LOCK;
ALTER USER 'furrywall'@'localhost' ACCOUNT UNLOCK;

参考链接

查看配置

# 查看helm安装Loki默认配置
[root@master ~]# helm inspect values loki/loki > loki.yaml
[root@master ~]# cat loki.yaml
# 部分配置
config:
  storage_config:
    boltdb:
      directory: /data/loki/index
    filesystem:
      directory: /data/loki/chunks
  table_manager:
    retention_deletes_enabled: false
    retention_period: 0

image:
  repository: grafana/loki
  tag: v1.2.0
  pullPolicy: IfNotPresent

## ref: https://kubernetes.io/docs/concepts/storage/persistent-volumes/
## If you set enabled as "True", you need :
## - create a pv which above 10Gi and has same namespace with loki
## - keep storageClassName same with below setting
persistence:
  enabled: false
  accessModes:
  - ReadWriteOnce
  size: 10Gi
  annotations: {}
  # subPath: ""
  # existingClaim:

配置循环删除

config:
  table_manager:
    retention_deletes_enabled: true
    # 注意是168的倍数:168 * 4
    retention_period: 672h

配置持久化

persistence:
  enabled: true
  accessModes:
  - ReadWriteOnce
  size: 100Gi
  annotations: {}
  existingClaim: loki-pvc

创建PVC

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: loki-pvc
  namespace: monitoring
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
        storage: 100Gi
  storageClassName: nfs-client
# 卸载重新安装
helm delete --purge loki
helm install loki/loki --name loki --namespace monitoring -f loki.yaml

# 升级命令
helm upgrade loki --values loki.yaml loki/loki

网络模式

Docker网络模式 配置 说明
host –net=host 容器和宿主机共享Network namespace。
container –net=container:NAME 容器和另外一个容器共享Network namespace。
none –net=none 容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配veth pair 和网桥连接,配置IP等。
bridge –net=bridge 默认为该模式

默认创建3种模式

[root@node1 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
fa18c3cc657d        bridge              bridge              local
c1196f6c46ca        host                host                local
c20416a61dd3        none                null                local

# 手动创建一个bridge网络
[root@node1 ~]# docker network create test
1ed592b9d91ae8c49f5de4b975e5adb104264bf3b03973fcf3040683a4dfcf0e
[root@node1 ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
fa18c3cc657d        bridge              bridge              local
c1196f6c46ca        host                host                local
c20416a61dd3        none                null                local
1ed592b9d91a        test                bridge              local

测试

# 启动两个容器
docker run -itd --name=c1 busybox
docker run -itd --name=c2 --net=test busybox

# 查看他们ip
docker exec -it c1 ip ad
docker exec -it c2 ip ad

# 因为使用的不同的bridge,他们之间ping不通
docker exec -it c2 ping 172.19.0.2
# 手动将c1加入到test网络
docker network connect test c1
# 查看c1网卡,会增加一个
docker exec -it c1 ip ad

与另一个容器共享一个网络IP

# 先启动一个
docker run -itd --name c1 busybox
# 共享另一个容器网络
docker run -itd --net=container:c1 --name c2 busybox

# 网卡完全一致
docker exec c1 ip ad
docker exec c2 ip ad

ThreadLocal

  • ThreadLocal类允许我们创建只能被同一个线程读写的变量,本质是一个Hash表,keyThread自身.
  • 主要方法: set() / get() / remove()

创建

// 不带初始值
ThreadLocal<String> str = new ThreadLocal<>();

// 带初始值
static ThreadLocal<String> str = new ThreadLocal<String>() {
    @Override
    protected String initialValue() {
        return "a";
    }
};

// java8便捷写法
ThreadLocal<String> str = ThreadLocal.withInitial(() -> "a");

使用

public static void main(String[] args) {
    new Thread(() -> {
//            str.set("aa");
        System.out.println(str.get()); // 初始化a
        str.remove(); // 用完主动释放,防止内存泄漏
    }).start();

    new Thread(() -> {
        str.set("bb");  //赋值
        System.out.println(str.get()); // 输出bb
        str.remove();   // 用完主动释放,防止内存泄漏
    }).start();
}

部署

# ccentos 7
yum install nginx

启动

systemctl start/stop/restart nginx

# 通过status查看nginx.conf配置文件位置
systemctl status nginx

修改配置

vim /etc/nginx/nginx.conf
# 修改默认端口80 -> 8080
listen       8080 default_server;
listen       [::]:8080 default_server;

# 检查配置是否正确,有successful表示可用
nginx -t 

# 重新加载配置文件
nginx -s reload

配置详解

...              // 全局块

events {         // events块
   ...
}

http      // http块
{
    ...   // http全局块
    server        // server块
    { 
        ...       // server全局块
        location [PATTERN]   // location块
        {
            ...
        }
        location [PATTERN] 
        {
            ...
        }
    }
    server
    {
      ...
    }
    ...     // http全局块
}
  1. 全局块:配置影响nginx全局的指令。一般有运行nginx服务器的用户组,nginx进程pid存放路径,日志存放路径,配置文件引入,允许生成worker process数等。
  2. events块:配置影响nginx服务器或与用户的网络连接。有每个进程的最大连接数,选取哪种事件驱动模型处理连接请求,是否允许同时接受多个网路连接,开启多个网络连接序列化等。
  3. http块:可以嵌套多个server,配置代理,缓存,日志定义等绝大多数功能和第三方模块的配置。如文件引入,mime-type定义,日志自定义,是否使用sendfile传输文件,连接超时时间,单连接请求数等。
  4. server块:配置虚拟主机的相关参数,一个http中可以有多个server
  5. location块:配置请求的路由,以及各种页面的处理情况。

nginx变量使用

# 变量申明
set $变量名 变量值

# 变量的引用
$变量名

预定义变量

常用变量

变量 作用
arg_参数名 URL中某个具体参数的值
query_string 与args变量完全相同
args 全部URL参数
is_args 如果请求的URL中有参数则返回?否则返回空
content_length HTTP 请求中标识包体长度的Content-Length头部的值,头部没有这个则为空
content_type 标识请求包体类型的Content-Type 头部的值
uri 请求的URI(不包含,不包含?后的参数)
document_uri 与uri完全相同
request_uri 请求的URL(包含?后的参数)
scheme 协议名 HTTP 或者 HTTPS
request_method 请求的方法GET 或者 POST
request_length 所有请求内容的大小,包括请求行,头部,包体等
remote_user 有HTTP Basic Authentication 协议传入的用户名
request 原始的url请求,含有方法和协议版本
cookie_COOKIE cookie COOKIE的值
http_HEADER HTTP请求头中的内容,HEADER为HTTP请求中的内容转为小写,-变为_(破折号变为下划线),例如:$http_user_agent(Uaer-Agent的值)
sent_http_HEADER HTTP响应头中的内容,HEADER为HTTP响应中的内容转为小写,-变为_(破折号变为下划线),例如: $sent_http_cache_control, $sent_http_content_type…;

TCP相关的变量

变量 作用
binary_remote_addr 客户端地质的整型格式,对于IPv4是4字节
remote_addr 客户端地址
remote_port 客户端端口
connection 递增的连接序号
connection_requests 当前连接上执行过的请求数,对keepalive 有意义
proxy_protocol_addr 若使用了proxy_protocol 协议则返回协议中的地址
proxy_protocol_port 若使用了proxy_protocol 协议则返回协议中的端口
server_addr 服务器端地址(本端地址)
server_port 服务器端端口
TCP_INFO tcp内核层参数($tcpinfo_rtt,$tcpinfo_rttvar,$tcpinfo_snd_cwnd,$tcpinfo_rcv_space)
server_protocol 服务端协议,例如 HTTP

Nginx处理请求过程中产生的变量

变量 作用
request_time 请求处理到现在的耗时
server_name 匹配上的请求server_name
request_completion 若请求处理完则返回OK,否则为空
request_id 以16禁止输出的请求标识id,随即生成

Nginx系统变量

变量 作用
time_local 以本地时间的标准输出
pid 所属worker进程的id
hostname 与系统上输出hostname 一致

PushGateway使用说明

  • Prometheus采用定时Pull模式,可能由于子网络或者防火墙的原因,不能直接拉取各个Target的指标数据,此时可以采用各个TargetPushGatewayPush数据,然后PrometheusPushGateway上定时pull
  • 其次在监控各个业务数据时,需要将各个不同的业务数据进行统一汇总,此时也可以采用PushGateway来统一收集,然后Prometheus来统一拉取
  • Prometheus每次从PushGateway拉取的数据,并不是拉取周期内用户推送上来的所有数据,而是最后一次PushPushGateway上的数据
  • 指标值只能是数字类型,非数字类型报错
  • 指标值支持最大长度为16位,超过16位后默认置为0

安装

# 默认不持久化数据
docker run -d -p 9091:9091 prom/PushGateway 

# 指定持久化文件和保留时间
docker run -d -p 9091:9091 prom/pushgateway "-persistence.file=pg_file –persistence.interval=5m"

测试

# 单条推送
echo "test_metric 123456" | curl --data-binary @- http://192.168.41.128:9091/metrics/job/test_job

# 多条推送
cat <<EOF | curl --data-binary @- http://192.168.41.128:9091/metrics/job/test_job/instance/test_instance
# TYPE test_metrics counter
test_metrics{label="app1",name="demo"} 100.00
# TYPE another_test_metrics gauge
# HELP another_test_metrics Just an example.
another_test_metrics 123.45
EOF

# 通过文件
vim pg.txt
# TYPE http_request_total counter
# HELP http_request_total get interface request count with different code.
http_request_total{code="200",interface="/v1/save"} 276
http_request_total{code="404",interface="/v1/delete"} 0
http_request_total{code="500",interface="/v1/save"} 1
# TYPE http_request_time gauge
# HELP http_request_time get core interface http request time.
http_request_time{code="200",interface="/v1/core"} 0.122

curl -XPOST --data-binary @pg.txt http://192.168.41.128:9091/metrics/job/app/instance/app-192.168.41.128

删除指标,参考官方

# {job="some_job",instance="some_instance"}
curl -X DELETE http://192.168.41.128:9091/metrics/job/some_job/instance/some_instance

# {job="some_job"}
curl -X DELETE http://192.168.41.128:9091/metrics/job/some_job

# 删除所有, 需要开启--web.enable-admin-api
curl -X PUT http://192.168.41.128:9091/api/v1/admin/wipe

通过SDK上传:

<dependency>
    <groupId>io.prometheus</groupId>
    <artifactId>simpleclient_pushgateway</artifactId>
    <version>0.7.0</version>
</dependency>
public static void main(String[] args) {
    try{
        String url = "192.168.41.128:9091";
        CollectorRegistry registry = new CollectorRegistry();
        Gauge guage = Gauge.build("my_custom_metric", "This is my custom metric.").create();
        guage.set(23.12);
        guage.register(registry);
        PushGateway pg = new PushGateway(url);
        Map<String, String> groupingKey = new HashMap<String, String>();
        groupingKey.put("instance", "my_instance");
        pg.pushAdd(registry, "my_job", groupingKey);
    } catch (Exception e){
        e.printStackTrace();
    }
}
public static void main(String[] args) {
    try{
        String url = "172.30.12.167:9091";
        CollectorRegistry registry = new CollectorRegistry();
        Gauge guage = Gauge.build("my_custom_metric", "This is my custom metric.").labelNames("app", "date").create();
        String date = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss").format(new Date());
        guage.labels("my-pushgateway-test-0", date).set(25);
        guage.labels("my-pushgateway-test-1", date).dec();
        guage.labels("my-pushgateway-test-2", date).dec(2);
        guage.labels("my-pushgateway-test-3", date).inc();
        guage.labels("my-pushgateway-test-4", date).inc(5);
        guage.register(registry);
        PushGateway pg = new PushGateway(url);
        Map<String, String> groupingKey = new HashMap<String, String>();
        groupingKey.put("instance", "my_instance");
        pg.pushAdd(registry, "my_job", groupingKey);
    } catch (Exception e){
        e.printStackTrace();
    }
}

查看

参考链接