SSH

news2024/11/16 15:45:38

简介

SSH:Secure Shell Protocol,安全的远程登录,实现加密通信,替代传统telnet协议。

端口:22/tcp

软件实现:

  • OpenSSH:ssh协议的开源实现,CentOS默认安装
  • Dropbear:另一个ssh协议的开源项目的实现

SSH协议版本:

  • V1:基于CRC-32做MAC,不安全
  • V2:双方主机协议选择安全的MAC方式,基于DH算法做秘钥交换,基于RSA或DSA实现身份验证

公钥交换原理

  • 客户端发起链接请求
  • 服务端返回自己的公钥,以及一个会话ID(这一步客户端得到服务端公钥)
  • 客户端生成密钥对
  • 客户端用自己的公钥异或会话ID,计算出一个值Res,并用服务端的公钥加密
  • 客户端发送加密后的值到服务端,服务端用私钥解密,得到Res
  • 服务端用解密后的值Res异或会话ID,计算出客户端的公钥(这一步服务端得到客户端公钥)
  • 最终:双方各自持有三个秘钥,分别为自己的一对公、私钥,以及对方的公钥,之后的所有通讯都会被加密

异或

如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。

a ^ b=c,则a ^ c =b,b ^ c=a。互相异或可得出另一个数

a

b

a^b

0

0

0

0

1

1

1

0

1

1

1

0

SSH加密通讯原理

OpenSSH

C/S架构;ssh协议的开源实现,CentOS默认安装

软件包

  • openssh
  • openssh-clients
  • openssh-server

服务器端程序:/usr/sbin/sshd

Unit文件:/usr/lib/systemd/system/sshd.service

客户端:

  • Linux:ssh、scp、sftp
  • Windows:Xshell、MobaXterm、Putty、SecureCRT

客户端SSH命令

ssh命令是ssh客户端,允许实现对远程系统经过验证的加密安全访问。

当用户远程访问ssh服务器时,会复制ssh服务器 /etc/ssh/ssh_host*key.pub 文件中公钥到客户机的 ~/.ssh/know_hosts 文件中;下次连接时,会自动匹配响应的私钥,不能匹配,将拒绝连接。

ssh客户端配置文件:/etc/ssh/ssh_config

首次登录是否检查,可设为 no
#StrictHostKeyChecking ask

私钥文件路径
#   IdentityFile ~/.ssh/id_rsa
#   IdentityFile ~/.ssh/id_dsa
#   IdentityFile ~/.ssh/id_ecdsa
#   IdentityFile ~/.ssh/id_ed25519

连接服务器端口
#   Port 22

格式

ssh user@host command

选项:

-p port:远程服务器监听的端口

-b:指定连接的源IP

-x:支持X11转发

-t:强制伪tty分配。

-o 选项:如-o StrictHostKeyChecking=no

-i:指定私钥文件路径,实现基于key验证,默认使用文件: ~/.ssh/id_dsa,
~/.ssh/id_ecdsa, ~/.ssh/id_ed25519,~/.ssh/id_rsa等

从 192.168.28.10 通过多个跳板登录 192.168.28.40
[root@centos8 ~]#ssh -t 192.168.28.20 ssh -t 192.168.28.30 ssh -t 192.168.28.40

[root@centos8 ~]#ssh -o StrictHostKeyChecking=no root@192.168.28.40 "cat /etc/os-release"
root@192.168.28.40's password:
NAME="Ubuntu"
VERSION="20.04.3 LTS (Focal Fossa)"
ID=ubuntu
...

在远程主机上执行本地脚本
[root@centos8 ~]#cat test.sh
#!/bin/bash
#********************************************************************
#FileName:     test.sh
#Version:      1.0
#Date:         2024-01-02
#Author:       wenzi
#Description: This is description
#********************************************************************
hostname -I
[root@centos8 ~]#ssh root@192.168.28.20 < test.sh
Pseudo-terminal will not be allocated because stdin is not a terminal.
root@192.168.28.20's password:
192.168.28.20

统计ssh登录失败次数最多的前2个远程IP 并 记录再 temp.txt 文件中
[root@wenzi ~]#lastb
root     ssh:notty    192.168.28.30    Tue Jan  2 13:48 - 13:48  (00:00)
root     ssh:notty    192.168.28.30    Tue Jan  2 13:48 - 13:48  (00:00)
root     ssh:notty    192.168.28.30    Tue Jan  2 13:48 - 13:48  (00:00)
root     ssh:notty    192.168.28.20    Tue Jan  2 13:47 - 13:47  (00:00)
root     ssh:notty    192.168.28.10    Tue Jan  2 13:47 - 13:47  (00:00)
root     ssh:notty    192.168.28.10    Tue Jan  2 13:47 - 13:47  (00:00)

btmp begins Tue Jan  2 13:47:26 2024
[root@wenzi ~]#lastb -f temp.txt | awk '{print $3}' | sort | uniq -c | sort -rn | head -n 2
      3 192.168.28.30
      2 192.168.28.10

其它ssh客户端工具

scp

scp 选项 源地址 目标地址

常见选项:

-r:递归复制

-P:指定远程主机监听的端口

-p:保持原文件的属性信息

-q:静默模式

rsync

rsync可以基于ssh和rsync协议实现高效的远程系统之间复制文件;比SCP更快,基于增量数据同步,只复制两方不同的文件。通信双方都需要安装rsync软件

rsync 选项 源地址 目标地址

rsync -av /etc ...表示复制目录和目录下的文件

rsync -av /etc/ ...只复制目录下文件

常见选项:

-v:显示详细过程

-a:以递归方式传输文件,并保持所有文件属性。相当于-rlptgod

-r:递归复制目录树

-p:保留权限

-t:保留修改时间戳

-g:保留组信息

-o:保留所有者信息

-l:将软链接文件本身进行复制(默认)

-L:将软链接文件指向的文件复制

-u:如果接受者文件比发送者文件新,将忽略同步

sshpass

自动登录ssh工具。多用在shell脚本中,无需输入密码(本机know_hosts文件中有的主机才能生效)

sshpass 选项 命令 参数

常见选项:

-p password:后面跟密码,直接登录远程服务器

-f 文件名:后跟保存密码的文件名,密码是文件内容的第一行

-e:将环境变量SSHPASS作为密码

SSH登录验证方式

  • 用户/口令
  • 秘钥

基于用户和口令验证

  1. 客户端发起ssh请求,服务器会把自己的公钥发送给用户(即上方公钥交换原理)
  2. 用户会根据服务器发来的公钥对密码进行加密。前两个过程
  3. 加密后的信息回传给服务器,服务器用自己的私钥解密,如果密码正确,则用户登录成功

注意:服务器端的公钥保存到客户端

基于秘钥验证

  1. 首先在客户端生成一对密钥(ssh-keygen)
  2. 并将客户端的公钥ssh-copy-id 拷贝到服务端
  3. 当客户端再次发送一个连接请求,包括ip、用户名
  4. 服务端得到客户端的请求后,会到authorized_keys中查找,如果有响应的IP和用户,就会随机生成一个字符串,如13579
  5. 服务端将使用客户端拷贝过来的公钥进行加密,然后发送给客户端
  6. 得到服务端发来的消息后,客户端会使用私钥进行解密,然后将解密后的字符串发送给服务端
  7. 服务端接受到客户端发来的字符串后,跟之前的字符串进行对比,如果一致,就允许免密码登录

注意:客户端的公钥保存到服务器端

实现基于秘钥登录

在客户端生成密钥对

-P给秘钥加密;-f指定秘钥保存位置,默认保存至 ~/.ssh/ 目录

ssh-keygen -t rsa [-P 'password'] [-f “~/.ssh/id_rsa"]
生成秘钥
[root@centos8 ~]#ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/root/.ssh/id_rsa):
Created directory '/root/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:+bcCLIGsYuC7JgDBcNBTqFSw9Nx+JKlG6NpIP3tGmOs root@centos8.magedu.com
The key's randomart image is:
+---[RSA 3072]----+
|==++.            |
|o+O . .          |
|.= * = .         |
|= . = +  .       |
|+o +o. +S        |
|==+o .o o.       |
|=.ooo  . .. .    |
|.o .oo    .. .   |
|o.oEo      ..    |
+----[SHA256]-----+

查看秘钥对
[root@centos8 ~]#ll /root/.ssh/
total 8
-rw------- 1 root root 2610 Jan  3 18:49 id_rsa    私钥
-rw-r--r-- 1 root root  577 Jan  3 18:49 id_rsa.pub    公钥
把公钥文件传输至远程服务器对应用户的家目录

-i指定公钥文件;复制到远程主机上后是 /root/.ssh/authorized_keys 文件

ssh-copy-id [-i [identity_file]] [user@]host
将本机公钥复制到远程主机上
[root@centos8 ~]#ssh-copy-id root@192.168.28.20
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/root/.ssh/id_rsa.pub"
The authenticity of host '192.168.28.20 (192.168.28.20)' can't be established.
ECDSA key fingerprint is SHA256:4n3yr6WWNPQlI+F3fUDh71yOMsibBLJMBjqJawfaEE0.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys
root@192.168.28.20's password:

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh 'root@192.168.28.20'"
and check to make sure that only the key(s) you wanted were added.


在远程主机上查看收到的公钥
[root@wenzi ~]#ll .ssh/
total 4
-rw------- 1 root root 577 Jan  3 18:50 authorized_keys
[root@wenzi ~]#cat .ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABgQDtXegd7leQgFRBYPoPtNHrSA7L5g6lSy2HAfFmM03OKas97yeRuATlmKekymUACHOVsP6CJQRm8Sn33y2aVJaQ8wcerm/+EFDVk7PWtrqIjyf8Hov6st64t4xEeIDIxjq6wqDGFqeZ0GPoI0HlQC2OBjSs9XAG0GCbqEOx7kUBYKBINWrq1K3wWiJDWrycV/AaHA7gI6nPctIwD4vrF44279CdVE+ih6QcRlglFyXZFTCDvdAeDIeyITZfe/Iie5Vlr1OKEFnbUYEmMfBZIG9YPo7DESYLi0J7UHr/om9j0r6e3HfmyqxUHTyvwp7ZFEa6BvnJwrbiejdFmflJmpecl96c1qzB/Jx/4y2Jbrp2kKWTCH4yiFBxuwpX3Ezws2Sn23F3o4pFpmy5AJp94RZKOPBM0/0v/a/tmDWxnr4h9eEKPiSE9l4SIYN1xFSvY59+gCNV3WWMEYvgxK5lsD2YAeRnzQuiUtXID6n/M6xs7KBHQyKhcmxLoqU9zbQuIBk= root@centos8.magedu.com
重设私钥口令
ssh-keygen -p

SSH服务器端配置

服务器端:sshd
服务器端的配置文件: /etc/ssh/sshd_config
服务器端的配置文件帮助:man 5 sshd_config

常用参数

Port  22                   默认的SSH端口,生产中建议修改
ListenAddress ip           指定SSH服务器监听的IP地址
LoginGraceTime 2m          在此时间内,如果用户未成功登录,连接将被终止。可防止暴力破解
PermitRootLogin yes        允许root用户登录,建议改为no;ubuntu默认禁止root远程登录
StrictModes yes            检查.ssh/文件的所有者,权限等
MaxAuthTries   6           用户在登录时尝试的最大次数,超过此次数,链接被终止
MaxSessions  10            一个客户端可以同时打开的最大SSH会话数
PubkeyAuthentication yes   允许使用公钥key进行身份验证
PermitEmptyPasswords no    禁止使用空密码登录   
PasswordAuthentication yes 允许密码验证登录,建议使用更安全的key验证登录
ClientAliveInterval 10     服务器将发送一个消息给客户端,检查它是否仍然活动的间隔时间(以秒为单位)。这有助于检测“僵尸”客户端连接。
ClientAliveCountMax 3      在此间隔时间内,服务器发送的消息的数量。如果达到这个数量而客户端没有响应,连接将被终止。
UseDNS yes                 在尝试解析远程用户名时使用DNS查找其IP地址,建议设置为no,可提高速度减少风险 
GSSAPIAuthentication yes   提高速度可改为no
MaxStartups                通常用于限制同时尝试连接到SSH服务的客户端的最大数量。它通常与ClientAliveInterval和ClientAliveCountMax一起使用,以防止暴力破解攻击。
Banner /path/file          当客户端尝试连接到SSH服务器时,它会显示指定的文件中的消息作为“横幅”。这通常用于显示警告消息或指导客户端如何正确登录

限制可登录用户方法

[root@centos8 ~]#vim /etc/ssh/sshd_config
...
AllowUsers user1 user2 user3
DenyUsers user1 user2 user3
AllowGroups g1 g2
DenyGroups g1 g2

[root@centos8 ~]#systemctl restart sshd

设置ssh空闲60s自动注销

[root@centos8 ~]#vim /etc/ssh/sshd_config
...
ClientAliveInterval   60
ClientAliveCountMax   0

[root@centos8 ~]#systemctl restart sshd

解决ssh登录缓慢的问题

[root@centos8 ~]#vim /etc/ssh/sshd_config
...
UseDNS no
GSSAPIAuthentication no

[root@centos8 ~]#systemctl restart sshd

ssh服务最佳实践

建议使用非默认端口
禁止使用protocol version 1
限制可登录用户
设定空闲会话超时时长
利用防火墙设置ssh访问策略
仅监听特定的IP地址
基于口令认证时,使用强密码策略,比如:tr -dc A-Za-z0-9_ < /dev/urandom | head -c 12| 
xargs
使用基于密钥的认证
禁止使用空密码
禁止root用户直接登录
限制ssh的访问频度和并发在线数
经常分析日志

案例

免输入密码直接登录目标主机

[root@centos8 ~]#sshpass -p admin ssh root@192.168.28.20

批量修改root密码为随机密码

[root@wenzi data]#vim chgpass.sh
#!/bin/bash
#********************************************************************
#FileName:     chgpass.sh
#Version:      1.0
#Date:         2024-01-02
#Author:       wenzi
#Description: This is description
#********************************************************************

rpm -q sshpass &> /dev/null && yum -y install sshpass &> /dev/null
#服务器原密码
export SSHPASS=123456
net=192.168.28

for i in {1..254};do
    {
    pass=`openssl rand -base64 9`
    sshpass -e ssh -o StrictHostKeyChecking=no ${net}.${i} "echo root:$pass | chpasswd"
    echo ${net}.${i}:${pass} >> host.txt
    }&
done
wait

基于key批量部署多台主机验证

[root@wenzi data]#cat keytest.sh
#!/bin/bash
#********************************************************************
#FileName:     keytest.sh
#Version:      1.0
#Date:         2024-01-03
#Author:       wenzi
#Description: This is description
#********************************************************************
hosts="
192.168.28.20
192.168.28.30
192.168.28.40
"
pass=wenzi
#-P表示无需给私钥加密;-f指定秘钥存储位置
ssh-keygen -P "" -f /root/.ssh/id_rsa &> /dev/null
rpm -q sshpass &> /dev/null || yum -y install sshpass &> /dev/null

for i in $hosts;do
    {
        sshpass -p $pass ssh-copy-id -o StrictHostKeyChecking=no -i /root/.ssh/id_rsa.pub $i &> /dev/null
    }&
done
wait

基于key实现多台主机无障碍互访

原理:多台主机共用一套秘钥

PASS=centos1
#设置网段最后的地址,4-255之间,越小扫描越快
END=254

IP=`ip a s eth0 | awk -F'[ /]+' 'NR==3{print $3}'`
#取IP前三位,即网段
NET=${IP%.*}.

. /etc/os-release

rm -f /root/.ssh/id_rsa
[ -e ./SCANIP.log ] && rm -f SCANIP.log

for((i=3;i<="$END";i++));do
    ping -c 1 -w 1  ${NET}$i &> /dev/null  && echo "${NET}$i" >> SCANIP.log &
done
wait

ssh-keygen -P "" -f /root/.ssh/id_rsa
if [ $ID = "centos" -o $ID = "rocky" ];then
    rpm -q sshpass || yum -y install sshpass
else
    dpkg -i sshpass &> /dev/null ||{ apt update; apt -y install sshpass; }
fi

sshpass -p $PASS ssh-copy-id -o StrictHostKeyChecking=no $IP 

AliveIP=(`cat SCANIP.log`)
for n in ${AliveIP[*]};do
    sshpass -p $PASS scp -o StrictHostKeyChecking=no -r /root/.ssh root@${n}:
done

#把.ssh/known_hosts拷贝到所有主机,使它们第一次互相访问时不需要输入回车
for n in ${AliveIP[*]};do
    scp /root/.ssh/known_hosts ${n}:.ssh/
done

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1352789.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Socket closed 异常解决方案:如何解决 JMeter 压测中的问题

问题描述 JMeter 压测时会报 java.net.SocketException: Socket closed java.net.SocketException: Socket closed at java.net.PlainSocketImpl.socketConnect(Native Method) at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350) at java.ne…

CMake入门教程【核心篇】宏模板(macro)

&#x1f608;「CSDN主页」&#xff1a;传送门 &#x1f608;「Bilibil首页」&#xff1a;传送门 &#x1f608;「本文的内容」&#xff1a;CMake入门教程 &#x1f608;「动动你的小手」&#xff1a;点赞&#x1f44d;收藏⭐️评论&#x1f4dd; 文章目录 1. 定义宏1.1 基本语…

红日靶场-3

目录 前言 外网渗透 外网渗透打点 1、arp 2、nmap 3、nikto 4、whatweb 5、gobuster 6、dirsearch CMS 1、主页内容 2、/configuration.php~ 目录 3、/administrator 目录 4、Joomla!_version探测 5、joomlascan python脚本 6、joomscan perl脚本 MySQL 1、远…

bootstrap5实现通用果蔬网站 FoodMart页面模板

一、需求分析 通用果蔬网站是指专门提供各类果蔬产品展示和销售的在线平台。它将不同种类的新鲜水果、蔬菜、干果、坚果等聚集在一起&#xff0c;为消费者提供方便、快捷的购物渠道。通用果蔬网站的作用主要包括以下几个方面&#xff1a; 商品展示和销售&#xff1a;通用果蔬网…

[DevOps-01] DevOps介绍

一、简要描述 DevOps&#xff1a;Development & Operations的缩写&#xff0c;也就是开发&运维 DevOps是一个不断提高效率并且持续不断工作的过程。 核心&#xff1a;简化Dev和Ops团队之间的流程&#xff0c;使整体软件开发过程更快速。 DevOps定义&#xff1a; DevOps…

4462 4.曙曙献爱心

#include<bits/stdc.h> using namespace std; int n,m,k; int a[1001]; int s[1001]; int f[1001][1001];//f[i][j]&#xff0c;i个警察&#xff0c;j个点&#xff0c;能管理的最大人数 int main(){cin>>n>>m>>k;for(int i1;i<n;i){cin>>a[i…

Langchain访问OpenAI ChatGPT API Account deactivated的另类方法,访问跳板机API

笔者曾经写过 ChatGPT OpenAI API请求限制 尝试解决 Account deactivated. Please contact us through our help center at help.openai.com if you need assistance. 结果如何&#xff1f; 没有啥用。目前发现一条曲线救国的方案。 1. 在官方 openai 库中使用 此处为最新Op…

什么是Maven ??? (以及关于依赖,中央仓库,国内源)

文章目录 什么是 Maven创建第一个 Maven 项目依赖管理Maven 的仓库Maven 如何设置国内源 什么是 Maven Maven &#xff1a;用于构建和管理任何基于java的项目的工具。**说白了就是管理 Java项目 的工具。**我们希望我们已经创建了一些东西&#xff0c;可以使Java开发人员的日常…

大一C语言基础知识点圈画1(结构体,共用体指针,数组字符串)

是所有成员占内存的总和吗&#xff1f; 不是&#xff0c; 非所有成员变量的内存总和

机器学习常用算法模型总结

文章目录 1.基础篇&#xff1a;了解机器学习1.1 什么是机器学习1.2 机器学习的场景1.2.1 模式识别1.2.2 数据挖掘1.2.3 统计学习1.2.4 自然语言处理1.2.5 计算机视觉1.2.6 语音识别 1.3 机器学习与深度学习1.4 机器学习和人工智能1.5 机器学习的数学基础特征值和特征向量的定义…

视频剪辑方法:掌握视频嵌套合并技术,释放无限创意

随着数字媒体的普及&#xff0c;视频剪辑已是创意表达的重要技巧。通过掌握视频嵌套合并技术&#xff0c;可以将多个视频片段融合在一起&#xff0c;创造出独特的视觉效果和故事叙述。现在一起看云炫AI智剪批量剪辑视频嵌套合并方法&#xff0c;释放无限创意。 准备视频素材&a…

知识库:提升客服效率的利器

相信大家都有过这样的经历&#xff1a;在需要帮助或解决问题时&#xff0c;与客服沟通却遇到了冗长的等待时间、低效的回答和重复的解决方案。这些问题不仅令人沮丧&#xff0c;也给企业带来了巨大的挑战。然而&#xff0c;随着技术的发展&#xff0c;客服系统中的知识库正逐渐…

sqlserver根据分组的内容分别查询出匹配的一条信息

需求场景&#xff1a; 我写了条分组语句&#xff0c; select name from car_machine_command group by name 然后该表有很多条相关的数据&#xff0c;我只想拿各个分组的一条数据看看即可 解决&#xff1a;可以使用窗口函数&#xff08;Window Function&#xff09;和 ROW_NU…

电磁波的信号加载说明

电磁波的信号加载电磁波(Electromagnetic wave)是由同相振荡 且互相垂直的电场与磁场在空间中衍生发射的振荡粒子波&#xff0c;是以波动的形式传播的电磁场&#xff0c;具有波粒二象性&#xff0c;其粒子形态称为光子&#xff0c;电磁波与光子不是非黑即白的关系&#xff0c;而…

【算法系列 | 11】深入解析查找算法之—插值查找

序言 心若有阳光&#xff0c;你便会看见这个世界有那么多美好值得期待和向往。 决定开一个算法专栏&#xff0c;希望能帮助大家很好的了解算法。主要深入解析每个算法&#xff0c;从概念到示例。 我们一起努力&#xff0c;成为更好的自己&#xff01; 今天第11讲&#xff0c;讲…

kbdnso.dll文件缺失,软件或游戏报错的快速修复方法

很多小伙伴遇到电脑报错&#xff0c;提示“kbdnso.dll文件缺失&#xff0c;程序无法启动执行”时&#xff0c;不知道应该怎样处理&#xff0c;还以为是程序出现了问题&#xff0c;想卸载重装。 首先&#xff0c;先要了解“kbdnso.dll文件”是什么&#xff1f; kbdnso.dll是Win…

拒绝纸张浪费,Paperless-ngx开源文档管理系统将纸质版转换成可搜索的电子版档案

GitHub&#xff1a;GitHub - paperless-ngx/paperless-ngx: A community-supported supercharged version of paperless: scan, index and archive all your physical documents 在线演示&#xff1a;https://demo.paperless-ngx.com 官网&#xff1a;https://docs.paperless-n…

rime中州韵小狼毫 inputShow lua Filter 输入字符透传滤镜

在 rime中州韵小狼毫 inputShow lua Translator 一文中&#xff0c;我们通过 inputShow.lua 定制了 inputShow_translator&#xff0c;这使得我们的输入方案可以将用户输入的字符透传到候选列表中来。如下&#x1f447;&#xff1a; &#x1f446;上图中我们在候选列表中看到了…

关于“Python”的核心知识点整理大全58

目录 19.2.3 注销 1. 注销URL urls.py 2. 视图函数logout_view() views.py 3. 链接到注销视图 base.html 19.2.4 注册页面 1. 注册页面的URL模式 urls.py 2. 视图函数register() views.py 3. 注册模板 register.html 4. 链接到注册页面 base.html 注意 19.3 …

[Unity]实时阴影技术方案总结

一&#xff0c;Planar Shadow 原理就是将模型压扁之后绘制在需要接受阴影的物体上&#xff0c;这种方式十分高效&#xff0c;消耗很低。具体实现过程参考Unity Shader - Planar Shadow - 平面阴影。具按照自己的理解&#xff0c;其实就是根据光照方向计算片元在接受阴影的平面…