Nginx代理
使用Nginx代理服务,使得服务器减少端口的开放数量,同时更加安全
编译模块
Nginx开启一些功能时,需要包含额外的功能模块,这些模块必须在Nginx安装之前,就通过编译添加。
因此,使用Nginx之前务必整理好自己想要的功能模块
查看Nginx原有的模块
nginx -V
本文使用OpenGauss,直接使用
dnf install nginx
安装,安装后已包含大部分模块,不再需要自行编译部分模块参考configure arguments中的内容
获取nginx源码
wget http://nginx.org/download/nginx-1.20.1.tar.gz
进入源码目录
cd nginx-1.20.1
更多版本详情:nginx: download
设置编译配置信息
./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_perl_module=dynamic --with-http_auth_request_module --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug
配置信息请自行考虑所需的模块
本文重点需要模块为:
- –with-http_ssl_module:启动SSL
- –with-http_v2_module:HTTP / 2的支持
更多模块信息参考:nginx编译安装配置模块大全_KH_FC的博客-CSDN博客
编译和安装
make
如果是首次安装,则输入
make install
在已安装nginx的基础上添加模块,只需覆盖原文件即可
cp ./objs/nginx /usr/share/nginx/sbin/
为了防止错误,请先备份原文件
cp /usr/share/nginx/sbin/nginx /usr/share/nginx/sbin/nginx.bak
开启SSL
安装OpenSSL
dnf -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel
生成SSL证书
openssl req -x509 -nodes -days 36500 -newkey rsa:2048 -keyout /etc/nginx/https/ssl.key -out /etc/nginx/https/ssl.crt
生成过程需要填写一系列证书的信息
- Country:单位所在国家,为两位数的国家缩写,如: CN 就是中国
- State/Province:单位所在州或省
- Locality:单位所在城市 / 或县区
- Organization:此网站的单位名称;
- Organization Unit:下属部门名称;也常常用于显示其他证书相关信息,如证书类型,证书产品名称或身份验证类型或验证内容等;
- Common Name:网站的域名;
- Email Address:邮箱地址
打开Nginx配置文件
vi /etc/nginx/nginx.conf
文件中补充内容,开启SSL
#------------------------------# #-----------原有的内容-----------# #------------------------------# http { #------------------------------# #-----------原有的内容-----------# #------------------------------# ssl_certificate https/ssl.crt; ssl_certificate_key https/ssl.key; ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #------------------------------# #-----------原有的内容-----------# #------------------------------# server { #------------------------------# #-----------原有的内容-----------# #------------------------------# listen 443 ssl http2; listen [::]:443 ssl http2; #------------------------------# #-----------原有的内容-----------# #------------------------------# } }
- Nginx配置文件代码均以分号结尾
- 新版本Nginx取消了使用
SSL ON
启动 - 本实例不使用http 80 端口访问,仅采用https 443 端口访问
- 本实例开启的http2是为了V2Ray端口转发使用,若无需求则可取消
普通文件
若需要代理html静态网页,或代理文件目录等本地文件
在Nginx配置文件的
server{......}
内插入如下内容root /usr/share/nginx/html;
其中
/usr/share/nginx/html
为本地存放代理文件的目录在此情况下,代理文件的访问路径为Nginx Web根目录
若想改变路径,则可插入如下内容
location /XXX/XXX/XXX/XXX/ { root /usr/share/nginx/html; }
其中
/XXX/XXX/XXX/XXX/
为访问Nginx Web时的目录对于文件目录等本地文件,需要防止自动运行index文件,并配置文件目录格式
以download目录作为本地文件为例,配置如下
location /download/{ autoindex on; autoindex_exact_size off; autoindex_localtime on; index ...; }
autoindex on:启动文件目录
autoindex_exact_size off:显示出文件的大概大小,单位是kB或者MB或者GB
autoindex_localtime on:显示的文件时间为文件的服务器时间
**index …**: 将默认index指向…
更多文件目录美化参考:Nginx浏览目录配置及美化_蓝色星空-CSDN博客_nginx目录浏览美化
为了处理部分中文乱码问题,在配置文件的
server{......}
内插入charset utf-8;
反向代理
本文全文配置文件如下:
# For more information on configuration, see:
# * Official English Documentation: http://nginx.org/en/docs/
# * Official Russian Documentation: http://nginx.org/ru/docs/
user nginx;
worker_processes auto;
error_log /var/log/nginx/error.log;
pid /run/nginx.pid;
# Load dynamic modules. See /usr/share/doc/nginx/README.dynamic.
include /usr/share/nginx/modules/*.conf;
events {
accept_mutex on;
multi_accept on;
worker_connections 1024;
}
http {
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status $body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main;
sendfile on;
tcp_nopush on;
tcp_nodelay on;
keepalive_timeout 65;
types_hash_max_size 2048;
proxy_headers_hash_max_size 51200;
proxy_headers_hash_bucket_size 6400;
ssl_certificate https/ssl.crt;
ssl_certificate_key https/ssl.key;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
include /etc/nginx/mime.types;
default_type application/octet-stream;
# Load modular configuration files from the /etc/nginx/conf.d directory.
# See http://nginx.org/en/docs/ngx_core_module.html#include
# for more information.
include /etc/nginx/conf.d/*.conf;
upstream Http {
server c216:80;
}
upstream JavaWeb {
server c216:8080;
}
upstream CodeServer_C216 {
server c216:8888;
}
upstream CodeServer_D413 {
server D413:8888;
}
upstream Hadoop {
server c216:9870;
}
upstream YARN {
server d413:8042;
}
upstream HttpFS {
server c216:14000;
}
upstream HadoopHistory {
server c216:19888;
}
upstream HBase {
server c216:16010;
}
upstream KunpengPortingAdvisor{
server c216:8084;
}
upstream KunpengHyperTuner{
server c216:8086;
}
upstream V2Ray{
server d413:11235;
}
upstream Aria{
server c216:6800;
}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name_in_redirect off;
root /usr/share/nginx/html;
charset utf-8;
# Load configuration files for the default server block.
include /etc/nginx/default.d/*.conf;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
absolute_redirect off;
location /Http/ {
proxy_pass http://Http/;
sub_filter ="/ ="/Http/;
sub_filter_once off;
}
location /download/{
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
index ...;
}
location /code/{
autoindex on;
autoindex_exact_size off;
autoindex_localtime on;
index ...;
}
location /JavaWeb/ {
proxy_pass http://JavaWeb/;
}
location /CodeServer_C216/ {
proxy_pass http://CodeServer_C216/;
}
location /CodeServer_D413/ {
proxy_pass http://CodeServer_D413/;
}
location /Hadoop/ {
proxy_pass http://Hadoop/;
sub_filter ="/ ="/Hadoop/;
sub_filter_once off;
auth_basic "请输入密码";
auth_basic_user_file /usr/share/nginx/htpasswd.users;
}
location /Hadoop/HttpFS/ {
sub_filter_types text/xml application/json application/javascript;
proxy_pass http://HttpFS/;
sub_filter http:// /Hadoop/;
sub_filter_once off;
auth_basic "请输入密码";
auth_basic_user_file /usr/share/nginx/htpasswd.users;
proxy_set_header Content-Type application/octet-stream;
}
location /Hadoop/YARN/ {
proxy_pass http://d413:8042/;
sub_filter ="/ ="/Hadoop/YARN/;
sub_filter_once off;
auth_basic "请输入密码";
auth_basic_user_file /usr/share/nginx/htpasswd.users;
}
location /Hadoop/HadoopHistory/ {
proxy_pass http://HadoopHistory/;
sub_filter ="/ ="/Hadoop/HadoopHistory/;
sub_filter http://d413:8042 /Hadoop/YARN/;
sub_filter_once off;
auth_basic "请输入密码";
auth_basic_user_file /usr/share/nginx/htpasswd.users;
}
location /Hadoop/HBase/ {
proxy_set_header Accept-Encoding "";
proxy_pass http://HBase/;
sub_filter ="/ ="/Hadoop/HBase/;
sub_filter_once off;
auth_basic "请输入密码";
auth_basic_user_file /usr/share/nginx/htpasswd.users;
}
location /KunpengPortingAdvisor/ {
proxy_pass https://KunpengPortingAdvisor/;
}
location /KunpengHyperTuner/ {
proxy_pass https://KunpengHyperTuner/;
}
location /V2Ray {
proxy_pass http://V2Ray;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection upgrade;
}
location /Aria/ {
proxy_pass https://Aria/;
}
rewrite ^/(jmx|conf|startupProgress)(.*) /Hadoop/$1$2 permanent;
rewrite ^/(httpfs|HttpFS)(.*) /Hadoop/HttpFS/$1 permanent;
rewrite ^/jobhistory(.*) /Hadoop/HadoopHistory/jobhistory$1 permanent;
rewrite ^/master-status(.*) /Hadoop/HBase/master-status$1 permanent;
rewrite ^/porting(.*) /KunpengPortingAdvisor/porting$1 permanent;
rewrite ^/user-management(.*) /KunpengHyperTuner/user-management$1 permanent;
rewrite ^/(sys|java)-perf(.*) /KunpengHyperTuner/$1-perf$2 permanent;
location /webhdfs/ {
set $flag_url 0;
if ( $arg_op ~ 'LISTSTATUS|MKDIRS|DELETE|GET_BLOCK_LOCATIONS') {
rewrite ^/(.*) /Hadoop/$1 permanent;
set $flag_url 1;
}
if ( $flag_url = 0){
set $args "$args&user.name=root";
rewrite ^/(.*) /Hadoop/HttpFS/$1 permanent;
}
}
error_page 404 /404.html;
location = /40x.html {
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
}
}
}
Aria
Aria是一款支持BT及磁力下载的免费软件
启动Aria,本文使用Aria的地址为:c216:6800
因为本文使用https连接,Aria也可以切换为https进行访问
在Aria的配置文件aria2.conf修改内容如下
# 是否启用 RPC 服务的 SSL/TLS 加密, # 启用加密后 RPC 服务需要使用 https 或者 wss 协议连接 rpc-secure=true # 在 RPC 服务中启用 SSL/TLS 加密时的证书文件(.pem/.crt) rpc-certificate=/etc/nginx/https/ssl.crt # 在 RPC 服务中启用 SSL/TLS 加密时的私钥文件(.key) rpc-private-key=/etc/nginx/https/ssl.key
将Aria加入到Nginx中,配置内容如下
#------------------------------# #-----------原有的内容-----------# #------------------------------# http { #------------------------------# #-----------原有的内容-----------# #------------------------------# upstream Aria{ server c216:6800; } #------------------------------# #-----------原有的内容-----------# #------------------------------# server { #------------------------------# #-----------原有的内容-----------# #------------------------------# location /Aria/ { proxy_pass https://Aria/; } #------------------------------# #-----------原有的内容-----------# #------------------------------# } }
upstream Aria:指定代理的服务地址
**location /Aria/**:指定代理在网页访问时的目录
proxy_pass:指定代理的服务地址
若不设定upstream,也可直接输入
proxy_pass https://c216:6800/;
Java Web
启动Java Web,本文使用Tomcat的地址为:c216:8080
将Java Web加入到Nginx中,配置同Aria,部分修改如下
upstream JavaWeb { server c216:8080; } location /JavaWeb/ { proxy_pass http://JavaWeb/; }
鲲鹏开发者套件
华为帮助开发者加速应用迁移和算力升级,提供鲲鹏开发套件,包括分析扫描、代码迁移、加速库、编译器和性能优化等一系列软件工具。
前往华为云下载开发者套件并安装启动
下载及安装教程:成长地图_鲲鹏开发套件_华为云 (huaweicloud.com)
本文安装其中的代码迁移工具(端口8084)和性能分析工具(端口8086)
将开发者套件加入到Nginx中,配置同Aria,部分修改如下
upstream KunpengPortingAdvisor{ server c216:8084; } upstream KunpengHyperTuner{ server c216:8086; } location /KunpengPortingAdvisor/ { proxy_pass https://KunpengPortingAdvisor/; } location /KunpengHyperTuner/ { proxy_pass https://KunpengHyperTuner/; }
同前文进行配置后,由于代理服务不在根目录,会发现网页跳转产生问题,此时需要重定向代理链接
配置如下
server { #------------------------------# #-----------原有的内容-----------# #------------------------------# rewrite ^/user-management(.*) /KunpengHyperTuner/user-management$1 permanent; rewrite ^/(sys|java)-perf(.*) /KunpengHyperTuner/$1-perf$2 permanent; #------------------------------# #-----------原有的内容-----------# #------------------------------# }
- rewrite:重定向到Nginx的访问链接
- *^/user-management(.)**:以正则表达式,按此格式匹配链接
- /KunpengHyperTuner/user-management$1:将原链接重定向为本链接,**$1为(.*)**匹配到的内容
- permanent:永久301重定向标记
教程参考:Nginx URL重写(rewrite)配置及信息详解 - Czlun - 博客园 (cnblogs.com)
CodeServer
远程网页端的Visual Stdio Code,可以方便远程编写程序、操控系统和文件处理
安装CodeServer
本文存在两台服务器,各安装了CodeServer,现通过Nginx同时代理两台服务器,从而方便操作
使用的服务地址为:c216:8888,d413:8888
将CodeServer加入到Nginx中,配置同Aria,部分修改如下
upstream CodeServer_C216 { server c216:8888; } upstream CodeServer_D413 { server D413:8888; } location /CodeServer_C216/ { proxy_pass http://CodeServer_C216/; } location /CodeServer_D413/ { proxy_pass http://CodeServer_D413/; }
此时通过Nginx访问CodeServer提示错误
The workbench failed to connect to the server (Error: WebSocket close with status code 1006)
配置文件补充内容如下
server { #------------------------------# #-----------原有的内容-----------# #------------------------------# proxy_set_header Connection upgrade; #------------------------------# #-----------原有的内容-----------# #------------------------------# }
- proxy_set_header:重新定义或添加字段传递给代理服务器的请求头
Hadoop
Hadoop是一个由Apache基金会所开发的分布式系统基础架构
安装Hadoop
本文使用的服务地址为:c216:9870(NameNode),d413:8042(YARN),c216:14000(HttpFS),c216:19888(HadoopHistory)
将Hadoop加入到Nginx中,并处理链接重定向问题,内容如下(此时内容不为最终版,可先不输入):
upstream Hadoop { server c216:9870; } upstream HadoopHistory { server c216:19888; } location /Hadoop/ { proxy_pass http://Hadoop/; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /Hadoop/HadoopHistory/ { proxy_pass http://HadoopHistory/; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } rewrite ^/(jmx|conf|startupProgress)(.*) /Hadoop/$1$2 permanent; rewrite ^/jobhistory(.*) /Hadoop/HadoopHistory/jobhistory$1 permanent;
auth_basic:访问Hadoop时设置密码,此处为显示提示
auth_basic_user_file:设置的密码文件
密码文件生成教程:
安装 htpasswd 工具
dnf -y install httpd-tools
设置用户名和密码,并把用户名、密码保存到指定文件中
htpasswd -c /usr/share/nginx/htpasswd.users user
user为指定用户名
此时,发现部分static等其他文件无法访问,同样是指向根目录问题
由于不同服务的指向不同,不能统一使用rewrite定向,遂使用其他办法(此时内容不为最终版,可先不输入):
upstream Hadoop { server c216:9870; } upstream HadoopHistory { server c216:19888; } location /Hadoop/ { proxy_pass http://Hadoop/; sub_filter ="/ ="/Hadoop/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /Hadoop/HadoopHistory/ { proxy_pass http://HadoopHistory/; sub_filter ="/ ="/Hadoop/HadoopHistory/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } rewrite ^/(jmx|conf|startupProgress)(.*) /Hadoop/$1$2 permanent; rewrite ^/jobhistory(.*) /Hadoop/HadoopHistory/jobhistory$1 permanent;
sub_filte:重写网页响应内容
=”/ =”/Hadoop/:将网页中格式为=“/xxxxxx的内容替换为=“/Hadoop/xxxxxx
在本文中,主要将诸如src=”/static/dust-full-2.0.0.min.js”的根目录引用修改为src=”/Hadoop/static/dust-full-2.0.0.min.js”
sub_filter_once off:使得所有匹配到的内容都被替换,而不是执行一次
重新设置后,发现部分网页无法访问,是由于YARN代理未开,处理如下(此时内容不为最终版,可先不输入):
upstream Hadoop { server c216:9870; } upstream YARN { server d413:8042; } upstream HadoopHistory { server c216:19888; } location /Hadoop/ { proxy_pass http://Hadoop/; sub_filter ="/ ="/Hadoop/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /Hadoop/YARN/ { proxy_pass http://d413:8042/; sub_filter ="/ ="/Hadoop/YARN/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /Hadoop/HadoopHistory/ { proxy_pass http://HadoopHistory/; sub_filter ="/ ="/Hadoop/HadoopHistory/; sub_filter http://d413:8042 /Hadoop/YARN/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } rewrite ^/(jmx|conf|startupProgress)(.*) /Hadoop/$1$2 permanent; rewrite ^/jobhistory(.*) /Hadoop/HadoopHistory/jobhistory$1 permanent;
尝试Hadoop的HDFS功能,发现部分上传、下载功能无法使用
Hadoop Web端默认使用webhdfs处理,而经过Nginx代理后出现问题,此时需要将webhdfs的部分功能转交给httpfs实现
最终Hadoop配置如下:
upstream Hadoop { server c216:9870; } upstream YARN { server d413:8042; } upstream HttpFS { server c216:14000; } upstream HadoopHistory { server c216:19888; } location /Hadoop/ { proxy_pass http://Hadoop/; sub_filter ="/ ="/Hadoop/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /Hadoop/HttpFS/ { sub_filter_types text/xml application/json application/javascript; proxy_pass http://HttpFS/; sub_filter http:// /Hadoop/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; proxy_set_header Content-Type application/octet-stream; } location /Hadoop/YARN/ { proxy_pass http://d413:8042/; sub_filter ="/ ="/Hadoop/YARN/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /Hadoop/HadoopHistory/ { proxy_pass http://HadoopHistory/; sub_filter ="/ ="/Hadoop/HadoopHistory/; sub_filter http://d413:8042 /Hadoop/YARN/; sub_filter_once off; auth_basic "请输入密码"; auth_basic_user_file /usr/share/nginx/htpasswd.users; } location /webhdfs/ { set $flag_url 0; if ( $arg_op ~ 'LISTSTATUS|MKDIRS|DELETE|GET_BLOCK_LOCATIONS') { rewrite ^/(.*) /Hadoop/$1 permanent; set $flag_url 1; } if ( $flag_url = 0){ set $args "$args&user.name=root"; rewrite ^/(.*) /Hadoop/HttpFS/$1 permanent; } } rewrite ^/(jmx|conf|startupProgress)(.*) /Hadoop/$1$2 permanent; rewrite ^/(httpfs|HttpFS)(.*) /Hadoop/HttpFS/$1 permanent; rewrite ^/jobhistory(.*) /Hadoop/HadoopHistory/jobhistory$1 permanent;
sub_filter_types:选定查找替换文件类型为文本型。默认只查找text/html文件
V2Ray
V2Ray 是一个网络转发程序,支持 TCP、mKCP、WebSocket 这3种底层传输协议,支持 HTTP、Socks、Shadowsocks、VMess 这4种内容传输协议(HTTP 只支持传入),并且有完整的 TLS 实现,是一个非常强大的平台。
教程参考:V2Ray 教程 (233v2.com)
安装配置V2Ray
一键安装脚本:
bash <(curl -s -L https://git.io/v2ray.sh)
安装后修改配置文件
vi /etc/v2ray/config.json
{ "log": { "access": "/var/log/v2ray/access.log", "error": "/var/log/v2ray/error.log", "loglevel": "warning" }, "inbounds": [ { "port": 11235, "protocol": "vmess", "settings": { "clients": [ { "id": "?????????????????", "level": 1, "alterId": 0 } ] }, "streamSettings": { "network": "ws", "wsSettings": { "connectionReuse": false, "path": "/V2Ray" } }, "sniffing": { "enabled": true, "destOverride": [ "http", "tls" ] } } /*------------------------------*/ /*-----------原有的内容-----------*/ /*------------------------------*/
其中**”port”: 11235可自行修改,“id”:**原封不动
参考教程:
将Hadoop加入到Nginx中:
upstream V2Ray{ server d413:11235; } location /V2Ray { proxy_pass http://V2Ray; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; }
端口映射
选择一个端口映射工具,本文使用免费的Sakura Frp
工具地址:Sakura Frp — 免费内网穿透_免费端口映射_高速_高防节点_不限流量_Minecraft我的世界_微信开发调试_群辉NAS_无需公网_免备案 (natfrp.com)
创建一个映射隧道,配置文件参考如下
[common] protocol = tcp server_addr = 映射服务IP server_port = 映射服务端口 user = 用户 token = ???????????? sakura_mode = true use_recover = true tcp_mux = true pool_count = 1 [隧道名] type = tcp local_ip = 127.0.0.1 local_port = 443 remote_port = 外网端口 auth_pass = 访问密码
在Nginx的服务器上安装Sakura Frp,并启动映射隧道
参考教程:Linux (natfrp.com)