一、缓存代理概述
1、代理的工作原理。
图1
我们从图1来解释一下squid的工作原理
首先客户机访问www.163.com的时候,首先到squid的缓存中进行查找如果有直接将结果应答给客户机,如果没有缓存则squid服务器想目www.163.com发送请求,将返回的结果存入自己的缓存并且应答给客户端。
squid可以代理的应用层协议有http、ftp。其中应用最广泛的是http。
HTTP代理的缓存对象主要是文字,图像等静态web元素,使用缓存机制后,当客户机在不同的时候
访问统一web元素,或者不同的客户机的访问相同的web元素时,可以直接从缓存服务器中获取结果,这
样就提高了用户向internet访问的速度。
使用squid代理服务器有以下几点好处:
1)加快了访问速度
2)隐藏了客户端的IP地址
3)可以对源地址尽心过滤
4)可以控制访问
2、代理的基本类型
根据实现的方式不同,代理服务可以分为传统代理和透明代理,这两种代理服务完成的工作相差不多,而还有一种代理也就是我们今天的重点反向代理
传统代理:在客户端使用的时候需要在web游览器中进行设置,来指定服务器的端口和地址,这种代理主要是针对局域网访问internet的时候用的比较广泛,但由于客户端需要进行设置,所以这种并不是最常用的。
透明代理:提供与传统代理相同的服务,但不需要用户进行设置,而是通过默认路由和防火墙的
重定向功能,在整个过程中用户不知道其中的过程,所以称之为透明代理。使用透明代理时网页浏
览器访问网站时的域名解析请求优先发给DNS服务进行解析。透明代理必须在linux操作系统的防火墙
上进行操作。操作上不是很灵活。
说完了两种正向代理,我们来看一反向代理的工作原理:
图2
客户端请求访问 WEB 服务时,DNS 将访问的域名解析为 Squid 反向代理服务器的 IP 地址,这样客户端的 URL 请求将被发送到反向代理服务器。如果 Squid 反向代理服务器中缓存了该请求的资源,则将该请求的资源直接返回给客户端,否则反向代理服务器将向后台的 WEB 服务器请求资源,然后将请求的应答返回给客户端,同时也将该应答缓存在本地,供下一个请求者使用。
Squid 反向代理一般只缓存可缓冲的数据(比如 html 网页和图片等),而一些 CGI 脚本程
序或者 ASP、JSP 之类的动态程序默认不缓存。它根据从 WEB 服务器返回的 HTTP 头标记来缓冲静
态页面。有四个最重要 HTTP 头标记:
Last-Modified: 告诉反向代理页面什么时间被修改
Expires: 告诉反向代理页面什么时间应该从缓冲区中删除
Cache-Control: 告诉反向代理页面是否应该被缓冲
Pragma: 用来包含实现特定的指令,最常用的是Pragma:no-cache
原理就说到这里。
二、安装squid及运行控制。
本例以squid3.4.6源码包进行演示,系统本本为centos6.5内核2.6.26 。
基本环境:gcc编译器,开发工具。
主机名:entos1.lzg.com
IP地址:192.168.1.1
ps:本次安装是以单台服务器作为安装,之后的代理验收的时候会有专门的拓扑图。
[root@centos1 tools]# ls squid-3.4.6/ -ld
rwxr-xr-x. 18 1000 1000 4096 Jun 25 2014 squid-3.4.6/
[root@centos1 tools]# cd squid-3.4.6
[root@centos1 squid-3.4.6]# ./configure --prefix=/usr/local/squid --syconfdir=/etc --enable-linux-netfilter --enable-linux-tproxy --enable-async-io=100 --enable-err-language="Simplify_Chinese" --enable-underscore --enable-poll --enable-gnuregex --enable-arp-acl
上述含义如下:
--prefix 指定安装的位置
--sysconfdir=/etc 指定配置文件的存放位置
--enable-linux-netfilter 使用内核进行过滤
--enable-linux-tproxy 支持透明模式
--enable-arp-acl 可以直接在规则中通过客户端MAC地址进行管理
--enable-async-io=100 提升存储性能 值一般都为100
--enable-err-language="Simplify_Chinese" 错误信息显示为中文
--enable-underscore 允许url路径存在下划线
--enable-poll 使用poll()模式,提升性能
--enable-gnuregex 使用正则表达式
[root@centos1 tools]# make && make install
[root@centos1 squid-3.4.6]# echo $?
使用变量$?来判断是否安装正确。返回0代表正确执行,squid我们就安装完成了,这是我们只需要做一下简单的配置即可。
因为squid默认不存在运行用户,我们先创建一个运行用户名为squid
[root@centos1 squid-3.4.6]# useradd -M -s /sbin/nologin squid
由于程序用户不需要宿主目录以及不需要登录操作系统,所以添加-M -s选项
现在我们来将他的执行程序链接到/usr/local/sbin目录下,方便命令的执行或者直接修改PATH环境变量。
这里我选择修改PATH环境变量
[root@centos1 squid-3.4.6]# echo "PATH=$PATH:/usr/local/squid/sbin/" >> /etc/profile
[root@centos1 squid-3.4.6]# . /etc/profile
之后我们将squid安装目录下的var子目录的属组和属主改变
[root@centos1 squid-3.4.6]# chown -R squid:squid /usr/local/squid/var
可以使用whilere看一下squid的主配置文件路径
[root@centos1 squid-3.4.6]# whereis squid
squid: /etc/squid.conf /usr/local/squid
我们来看一下squid的默认的配置文件内容
[root@centos1 squid-3.4.6]# vim /etc/squid.conf
#
# Recommended minimum configuration:
#
# Example rule allowing access from your local networks.
# Adapt to list your (internal) IP networks from where browsing
# should be allowed
#下面的部分为程序定义的acl规则
acl localnet src 10.0.0.0/8 # RFC1918 possible internal network
acl localnet src 172.16.0.0/12 # RFC1918 possible internal network
acl localnet src 192.168.0.0/16 # RFC1918 possible internal network
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl CONNECT method CONNECT
#
# Recommended minimum Access Permission configuration:
#
# Deny requests to certain unsafe ports
http_access deny !Safe_ports
# Deny CONNECT to other than secure SSL ports
# Only allow cachemgr access from localhost
http_access allow localhost manager
http_access deny manager
# web applications running on the proxy server who think the only
# one who can access services on "localhost" is a local user
#http_access deny to_localhost
#
# INSERT YOUR OWN RULE(S) HERE TO ALLOW ACCESS FROM YOUR CLIENTS
#
# Example rule allowing access from your local networks.
# from where browsing should be allowed
#以http开头的为调用上面定义的acl规则
http_access allow localnet
http_access allow localhost
# And finally deny all other access to this proxy
http_access deny all
# Squid normally listens to port 3128
http_port 3128
# Uncomment and adjust the following to add a disk cache directory.
#cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256
# Leave coredumps in the first cache dir
coredump_dir /usr/local/squid/var/cache/squid
#
# Add any of your own refresh_pattern entries above these.
#
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern . 0 20% 4320
以上的配置项主要定义程序运行时需要的一些组件,和监听地址、端口号。其中实现代理主要就是通过这个配置文件来实现的,和我们今天后面需要讲解的acl也是需要应用在这个配置文件中,所以一定要及时进行备份,更多的配置项请参/etc/squid.conf.documented
我们先进性配置文件的修改,主要修改有以下几条配置项,有的配置项需要修改,而有的配置项需要添加。
http_port 3128 squid的默认监听端口tcp 修改
cache_effective_group squid squid的运行组 添加
cache_effective_user squidsquid的运行用户 添加
visible_hostname centos1.lzg.com 当前系统的主机名 添加
cache_dir ufs /usr/local/squid/var/cache/squid 100 16 256
上条配置项为缓存的目录位置其中
100代表缓存的大小
16表示最多可以有多少个一级子目录
256表示最多可以有多多少个二级子目录。
以上就是需要修改的配置文件内容。
我们保存之后使用语法检测工具对语法进行检查。
[root@centos1 squid-3.4.6]# squid -k parse
会输出很多信息,只要细看一下有没有出现错误就可以了。
语法没有任何错误,
我么首先对缓存目录进行初始化。
[root@centos1 squid-3.4.6]# squid -z
[root@centos1 squid-3.4.6]# echo $?
正确执行了,之后我们启动squid
[root@centos1 squid-3.4.6]# squid
[root@centos1 squid-3.4.6]# netstat -anpt | grep "squid"
tcp 0 0 :::3128 :::* LISTEN 37749/(squid-1)
可以看见我们的squid服务已经启动了,并且也看见监听的端口,地址以及进程号。为了更好的控制squid的服务,我们可以编写一个脚本来控制squid的服务。
[root@centos1 squid-3.4.6]# vim /tools/squid
#!/bin/bash
# chkconfig: 2345 90 25
# config: /etc/squid.conf
# pidfile: /usr/local/squid/var/run/squid.pid
# Description: Squid - internet object cache.
PID="/usr/local/squid/var/run/squid.pid"
CONF="/etc/squid.conf"
CMD="/usr/local/squid/sbin/squid"
case "$1" in
start)
netstat -anpt | grep squid &> /dev/null
if [ $? -eq 0 ]
then
echo "squid is running"
else
echo "正在启动squid..."
$CMD
fi
;;
stop)
$CMD -k kill &> /dev/null
rm -fr $PID &> /dev/null
;;
status)
[ -f $PID ] &> /dev/null
if [ $? -eq 0 ]
then
netstat -anpt | grep squid
else
echo "squid is not running."
fi
;;
restart)
$0 stop &> /dev/null
echo "正在关闭squid..."
$0 start &> /dev/null
echo "正在启动squid..."
;;
reload)
$CMD -k reconfigure
;;
check)
$CMD -k parse
;;
*)
echo "用法:$0 {start | stop | restart | reload | check | status}"
;;
esac
以上脚本使用了我们之前的cass语句。
之后将squid脚本添加为系统服务,并设置每次开机自动运行
[root@centos1 squid-3.4.6]# cp /tools/squid /etc/init.d/
[root@centos1 squid-3.4.6]# chmod +x /etc/init.d/squid
[root@centos1 squid-3.4.6]# chkconfig --add squid
[root@centos1 squid-3.4.6]# chkconfig squid on
[root@centos1 squid-3.4.6]# service squid start
squid is running
[root@centos1 squid-3.4.6]# service squid restart
正在关闭squid...
正在启动squid...
这个服务与之前的系统服务没有什么区别,只是简化了一些。基本的配置就完成了,下面我们开始构建代理服务器
三、构建代理服务器
1、传统代理:
我们通过一个案例案进行解读
现在局域网内部需要通过域名www.qwe.com访问web服务器,由于并发访问量过多,公司现在要求加快访问internet的速度,决定采用传统代理的方式。
公司要求禁止通过代理下载超过100MB的文件
实验步骤:
1)在外网的DNS添加一个A记录记录的IP地址执行squid服务器的地址
2)修改squid。conf配置文件实现公司的需求。
由于是测试环境,这里只需要三台计算机就可以了。并且与internet的IP地址采用了同一个网段,这里linux网关服务区兼squid代理服务器需要开启路由转发并且需要设置iptables的snat共享上网。
实验拓扑就按图3搭建。
开始实验
web/dns
建一个a记录ip地址指向web服务器地址。
安装iis7.0不需要做任何配置。
squid/linux网关服务器
DNS指向dns服务器
开启路由转发
[root@centos1 ~]# echo "1" > /proc/sys/net/ipv4/ip_forward
建立防火墙规则
[root@centos1 ~]# iptables -t nat -F
[root@centos1 ~]# iptables -t nat -I POSTROUTING -o eth0 -s 192.168.1.0/24 -j SNAT --to 172.16.16.1
[root@centos1 logs]# iptables -I INPUT -p udp --dport 53 -j ACCEPT
[root@centos1 ~]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
将防火墙规则保存
squid/linux网关服务器
vim /etc/squid.conf
reply_body_max_size 10 MB 限制最大缓存大小
http_access allow localnet 允许所有地址使用squid缓存 需要在http_access_之前添加,具体为什么,我们之后在讲解。
acl domain dstdomain .qwe.com 定义可以缓存的目标域,匹配域内所有站点 如果需要访问多个网站则使用空格为分隔符写入就好了
http_access allow domain 应用acl规则
dns_children 40 MB 定义dns缓存的大小
[root@centos1 ~]# service squid restart
重新加载配置文件
局域网pc
在web游览器中找到工具——internet选项——点击链接选项卡——局域网(LAN)设置
按照下图所写输入
图5
现在可以通过www.qwe.com上网了
到此为止传统代理就做完了。
总结一下:我们主要就是在dns服务器上建立一个a记录,在squid服务器上允许了所有的地址使用squid,并且可以缓存qwe.com目标域的所有地址,并且在网关上开启路由转发,并且可以共享上网,允许53端口入站。配置客户端指向squid缓存代理
ps:如果不用域名的时候不用这么麻烦,网关什么都不需要操作,也不需要开启路由转发,只需要修改配置文件即可
通过上面的配置我们可以看出局域网有少量的PC时还可以应用,但是一旦数量过多的时候就不好设置了,这时我们可以通过透明代理,前面说过了,透明代理,不需要在客户端进行任何操作。
拓扑图还是一样
默认的squid.conf配置文件并不支持透明代理,这里我们只需在配置文件中修改一下就可以了。
前面说过了透明代理必须设置在网关上,否则是不能进行配置的,这是为什么呢?我们可以想象一下客户端访问网站的过程,首先客户端访问的目标端口为80或443端口去访问网站,网站收到之后响应请求之后建立连接,这是整个过程,但是中间加了一个缓存代理之后,就不一样了,因为有了代理客户端访问的目标地址其实是squid代理服务器,这时目标端口依然是80或443,squid代理服务器不可能响应客户端的请求,因为squid代理服务并不监听80或443端口。所以这里需要将80或443端口重定向为3128端口这是squid服务器就可以响应客户端的请求了,根据数据包的头部进行判断,如果缓存中存在则直接应答,如果不存在则访问之后应答。
2、配置透明代理
我们开始进行透明代理的案例:
squid/网关服务器
[root@centos1 ~]# vim /etc/squid.conf
http_port 192.168.1.1: 3128 transparent
这个地址就是连接局域网接口的IP地址,后面的是开启透明模式的选项。
之后在防火墙上添加两条规则
[root@centos1 logs]# iptables -t nat -nL
[root@centos1 logs]# iptables -t nat -I PREROUTING -s 192.168.1.0 -i eth1 -p tcp --dport 80 -j REDIRECT --to 3128
[root@centos1 logs]# iptables -t nat -I PREROUTING -s 192.168.1.0 -i eth1 -p tcp --dport 443 -j REDIRECT --to 3128
上诉两条规则就是将来自以192.168.1.0的http或https请求交给了3128端口进行处理
[root@centos1 logs]# service iptables save
iptables: Saving firewall rules to /etc/sysconfig/iptables:[ OK ]
将防火墙的规则进行保存。
现在我们将客户端上指定的缓存服务器地址去掉
去掉勾之后在使用域名访问
如果访问不成功的时候,建议将之前的操作全部删除,并且将iptables规则表全部清除重新启动计算机在重新配置防火墙,在将之前删除的配置项恢复回来,在访问就可以了。
3.反向代理:
我们之后在演示如何构建反向代理,因为反向代理还需要重新编译安装,所以我们先来看一下今天的第三个给内容acl
四、ACL访问控制
squid提供了强大的代理控制机制,通过合理的设置acl并进行限制,可以针对源地址,目标地址,目标url路径等条件进行过滤,
在配置文件中ACL需要通过两个步骤来实现:其一,使用acl配置项定义需要过滤的条件,之后使用http_access 的方式应用允许或者拒绝。
1、定义访问控制列表
每一行acl配置可以定义一条访问控制列表,格式如下。
acl 列表名称 列表类型 列表内容
其中列表名称有管理员自行定义,用来识别控制条件“列表类型必须使用squid预定义的值对应不同类别的控制条件;列表内容是要具体控制的对象列表内容可以有多个,使用空格间隔。”
我们来看一下具体的列表类型分别对应了那些列表内容
列表类型
列表内容
用途、含义
Src
192.168.1.100
源IP地址、网段、IP范围
192.168.1.0/24
192.168.1.0-192.168.3.0/24
dst
216.163.137.3
目标IP地址、网段、主机名
67.135.167.0/24
www.lzg.com
Port
80 443 8080 21 20
目标端口
Dstdomain
.qq.com .sina.com
目标域、匹配域内所有站点
Time
MTWHFAS
12:30-13:00
M-Monday、T-Tuesday、W-Wednesday 、H-Thursday
F-Friday、A-Saurday、S-Sunday
maxconn
20
每个客户的并发连接数
url_regex
url_regex -i ^rtsp://
目标资源的RUL路径 -i不区分大小写
urlpath_regex
Urlpath_regex -i /.mp3 /.png /.mp4
目标资源的整个URL路径 -i表示忽略大小写
下面我来写几个规则并解释,但是不验证结果。
[root@centos1 ~]# vim /etc/squid.conf
acl localhost src 127.0.0.1/255.255.255.255 //源地址为127.0.0.1
acl MYLANsrc 192.168.1.0/24 192.168.4.0./24
acl to_localhost dst 127.0.0.0/8 //目标地址为127.0.0.0/8网段
acl MC20 maxconn 20 //最大并发连接数20
acl BlackURL url_regex -i ^rtsp:// ^emule //以rtsp开头的 ^开头
acl MEDIAFILE urlpath_regex -i \.mp3$ /.mp4$ //以mp3、MP4、为结尾$结尾
acl WORKTIME time MTWHF 08:30-17:30 //时间为周一至周五8:30-17:30
上面规则定义好了,下面使用http_access 来确定允许还是拒绝。
http_access deny BlackURL //拒绝以rtsp开头的url路径
http_access deny MEDIAFILE //拒绝以.mp3 .mp4结尾的完整url路径
http_access deny MC20 //并发量超过20时江北拒绝
http_access allow MYLAN WORKTIME //允许1.0 4.0网段在工作时间上网
http_access dney all/默认禁止所有客户机使用代理
执行访问控制室时,squid将按照各规则顺序依次检查,如果找到一条规则匹配就停止(有点类似以路由器的acl)因此规则的顺序安排是非常重要的有两点需要注意
没有设置任何规则时squid服务器将拒绝所有客户端的请求
有规则但没有找到匹配的规则:squid则与最后一条规则相反的权限,即最后一条为允许,那么就拒绝反之就是允许
策略上最好将常用的规则放到前面,这样可以减轻squid的负担,在访问控制的整体策略上建议采用先拒绝后允许的方式,先拒绝小范围,在允许大范围。。以上所讲就是acl的内容我们做一个实验来看一下acl的具体应用
1、需求:1.局域网的主机在上班时间可以使用代理服务。2.WEB站点的图片(gif)拒绝访问
2、验证:图片被拒绝浏览
[root@centos1 ~]# vim /etc/squid.conf
acl image urlpath_regex -i \.png$
acl WORKTIME time MTWHF 08:30-17:50
acl LAN_IP src 192.168.1.0/24
http_access deny image
http_access LAN_IP WORKTIME
已经不能访问到图片了,但是还是可以访问网站的只是以.png为结尾的图片不能访问了以.jpg格式的图片还是可以访问的
文章浏览阅读3.8k次。1、将下载好的萤石js插件,添加到SoringBoot项目中。位置可参考下图所示。(容易出错的地方,在将js插件在html页面引入时,发生路径错误的问题)所以如果对页面中引入js的路径不清楚,可参考下图所示存放路径。2、将ezuikit.js引入到demo-live.html中。(可直接将如下代码复制到你创建的html页面中)<!DOCTYPE html><html lan..._ezuikit 测试的url
文章浏览阅读322次。第二步,在弹出的对话框选择,设备驱动—>PLC—>莫迪康—>ModbusRTU—>COM,根据配置软件选择的协议选期期,这里以此为例,然后点击“下一步”。第四步,把使用虚拟串口打勾(GPRS设备),根据需要选择要生成虚拟口,这里以选择KVCOM1为例,然后点击“下一步”设备ID即Modbus地址(1-255) 使用DTU时,为下485接口上的设备地址。第六步,Modbus的从机地址,与配置软件相同,这里以1为例,点击“下一步“第五步,Modbus的从机地址,与配置软件相同,这里以1为例,点击“下一步“_组态王ua
文章浏览阅读9.4k次,点赞22次,收藏19次。安装npm相当于安装node.js,Node.js已自带npm,安装Node.js时会一起安装,npm的作用就是对Node.js依赖的包进行管理,也可以理解为用来安装/卸载Node.js需要装的东西_npm安装配置
文章浏览阅读748次,点赞21次,收藏26次。大家好,小编来为大家解答以下问题,python基础训练100题,python入门100例题,现在让我们一起来看看吧!宝子们还在新手村练级的时候,不单要吸入基础知识,夯实自己的理论基础,还要去实际操作练练手啊!由于文章篇幅限制,不可能将100道题全部呈现在此除了这些,下面还有我整理好的基础入门学习资料,视频和讲解文案都很齐全,用来入门绝对靠谱,需要的自提。保证100%免费这不,贴心的我爆肝给大家整理了这份今天给大家分享100道Python练习题。大家一定要给我三连啊~
文章浏览阅读1k次。 为了在 Linux ( Ubuntu) 上安装sublime,一般大家都会选择常见的教程或是 sublime 官网教程,然而在国内这种方法可能失效。为此,需要用安装包安装。以下就是使用官网安装包安装的教程。打开 sublime 官网后,点击右上角 download, 或是直接访问点击打开链接,即可看到各个平台上的安装包。选择 Linux 64 位版并下载。下载后,打开终端,进入安装..._ubuntu 安装sumlime text打不开
文章浏览阅读563次,点赞13次,收藏6次。CrossOver24是一款类虚拟机软件,专为macOS和Linux用户设计。它的核心技术是Wine,这是一种在Linux和macOS等非Windows操作系统上运行Windows应用程序的开源软件。通过CrossOver24,用户可以在不购买Windows授权或使用传统虚拟机的情况下,直接在Mac或Linux系统上运行Windows软件和游戏。该软件还提供了丰富的功能,如自动配置、无缝集成和实时传输等,以实现高效的跨平台操作体验。
文章浏览阅读1.7k次。一个用聊天的方式让ChatGPT帮我写的线程安全的环形List_为什么gpt一写list就卡
文章浏览阅读336次。我们在前面的文章里曾写过Web应用中乱码产生的原因和处理方式,旧文回顾:深度揭秘乱码问题背后的原因及解决方式其中我们提到可以通过Filter的方式来设置请求和响应的encoding,来解..._filterconfig selectencoding
文章浏览阅读651次。转自:http://www.jb51.net/article/36480.htmencodeURI和decodeURI是成对来使用的,因为浏览器的地址栏有中文字符的话,可以会出现不可预期的错误,所以可以encodeURI把非英文字符转化为英文编码,decodeURI可以用来把字符还原回来_js encodeur decodeurl
文章浏览阅读1.9w次,点赞6次,收藏3次。前言在日常的Android开发当中,我们肯定要打包apk。但是今天我打包的时候遇到一个很奇怪的问题Android The destination folder does not exist or is not writeable,大意是目标文件夹不存在或不可写。出现问题的原因以及解决办法上面有说报错的中文大意是:目标文件夹不存在或不可写。其实问题就在我们的打包界面当中图中标红的Desti..._the destination folder does not exist or is not writeable
文章浏览阅读94次。一、配置代码编辑区的样式 <1>打开Eclipse,Help —> Install NewSoftware,界面如下: <2>点击add...,按下图所示操作: name:随意填写,Location:http://eclipse-color-th..._ecplise高大上设置
文章浏览阅读2.8k次。一,下载mysql:http://dev.mysql.com/downloads/mysql/; 打开页面之后,在Select Platform:下选择linux Generic,如果没有出现Linux的选项,请换一个浏览器试试。我用的谷歌版本不可以,换一个别的浏览器就行了,如果还是不行,需要换一个翻墙的浏览器。 二,下载完后解压缩并放到安装文件夹下: 1、MySQL-client-5.6.2_linux mysql 安装 mysql-5.6.24-1.linux_glibc2.5.x86_64.rpm-bundle