Telnet: Great for Testing if a TCP Port is Open (and Remote Login)

Telnet is commonly used to check if a TCP connection to a specific port succeeds — essentially testing whether the port is open and reachable. Note that telnet itself is TCP-based, so it cannot test UDP sockets.

Syntax Basic:

telnet [options] host [port]

More complete:

telnet [-8acdEfFKLrx] [-b<host_alias>] [-e<escape_char>] [-k<realm>] [-l<user>] [-n<tracefile>] [-S<tos>] [-X<authtype>] [host [port]]

Quick background Telnet is the classic remote login client based on the TELNET protocol. It lets you run commands on a remote server as if you were sitting in front of it. You log in with username/password, but everything (including credentials) is sent in clear text — very insecure. Most modern Linux servers disable telnet and use SSH instead.

That said, curl can test HTTP services, and telnet can too (more on that below).

For UDP testing, use:

  • nc -u
  • nmap -sU
  • tcpdump
  • Application-level tools like dig for DNS

Common options

  • -4 Force IPv4
  • -6 Force IPv6
  • -8 Allow 8-bit data
  • -a Attempt automatic login (rarely used now)
  • -b<alias> Use alias for host
  • -e<char> Set escape character (default Ctrl+]) Example: telnet -e ^X host port
  • -l<user> Specify login user (for traditional telnet servers) Example: telnet -l root 192.168.1.10
  • -n<file> Log session to file (great for debugging)

In interactive mode After connecting, press Ctrl+] to enter telnet command mode. Useful commands:

  • quit Exit telnet
  • close Close current connection
  • status Show connection status
  • open host port Connect to new host/port
  • set localecho Enable local echo
  • toggle crlf Toggle CR/LF handling

Examples

  1. Connect to a remote telnet service
telnet 192.168.120.206

(or by domain: telnet www.baidu.com)

If it fails:

  • Check IP/address
  • Is the host up?
  • Routing correct? (route)
  • Is telnet service running? (netstat -tlnp → look for TCP 23 LISTEN)
  • Firewall allowing port 23? (iptables -L)
  1. Test TCP reachability (the 80% use case)
telnet 127.0.0.1 6379

Outcomes:

  • Connected → port open and TCP reachable
  • Connection refused → port not listening
  • Connection timed out → network/firewall issue
  1. As a generic TCP client Telnet doesn’t care about application protocols — it just sends whatever you type over TCP. Perfect for quick testing of text-based protocols.

HTTP example:

telnet example.com 80
GET / HTTP/1.1
Host: example.com

(then hit Enter twice)

Redis example:

telnet 127.0.0.1 6379
PING

→ +PONG

Typical telnet service config (/etc/xinetd.d/telnet)

service telnet
{
    disable = no
    flags = REUSE
    socket_type = stream
    wait = no
    user = root
    server = /usr/sbin/in.telnetd
    log_on_failure += USERID
}

Restrict access:

only_from = 10.0.0.2
no_access = 10.0.0.{2,3,4}
access_times = 9:00-12:00 13:00-17:00
bind = 10.0.0.2

Limitations

  • Clear-text transmission of credentials → never use for real logins in production (use SSH)
  • Can’t test UDP
  • Binary protocols will garble output → stick to text protocols

Modern role: Telnet is best positioned as a quick TCP port/text-protocol debugging tool, not a login method.

Related tools

  • nc/netcat → Swiss army knife for TCP/UDP
  • curl → HTTP/HTTPS testing
  • ssh → Secure remote login
  • nmap → Port scanning (including UDP)

telnet登入远程主机、测试TCP链接是否可达

功能说明:telnet可以用于测试TCP socket链接是否连通(某个TCP端口是否开放)。但telnet不能测试 UDP socket链接,因为telnet基于TCP 协议,不支持 UDP。

语  法:

1 基本命令格式

telnet [选项] 主机 [端口]

2 复杂命令格式

telnet [-8acdEfFKLrx][-b<主机别名>][-e<脱离字符>][-k<域名>][-l<用户名称>][-n<记录文件>][-S<服务类型>][-X<认证形态>][主机名称或IP地址<通信端口>]

补充说明:

1telnet一般用于登入远程主机,与之类似的工具是ssh。telnet程序是基于TELNET协议的远程登录客户端程序。Telnet协议是TCP/IP协议族中的一员,是Internet远程登陆服务的标准协议和主要方式。它为用户提供了在本地计算机上完成远程主机工作的 能力。在终端使用者的电脑上使用telnet程序,用它连接到服务器。终端使用者可以在telnet程序中输入命令,这些命令会在服务器上运行,就像直接在服务器的控制台上输入一样。可以在本地就能控制服务器。要开始一个 telnet会话,必须输入用户名和密码来登录服务器。但是telnet因为采用明文传送报文,安全性不好,很多Linux服务器都不开放telnet服务,而改用更安全的ssh了。

2 curl可以测试HTTP服务,telnet也可以测试HTTP服务。

3 那怎么测UDP?可以使用以下工具:

  • nc -u
  • nmap -sU
  • tcpdump
  • 应用层工具dig测试DNS

选  项:

-4    强制IPv4地址解析

-6    强制进行IPv6地址解析

-8   允许使用8位字符资料,包括输入与输出。

-a   尝试自动登入远端系统(已很少使用)。

-b<主机别名>   使用别名指定远端主机名称。

-c   不读取用户专属目录里的.telnetrc文件。

-d   启动排错模式。

-e<脱离字符>   设置escape字符(默认是 Ctrl + ]),用于优雅退出telnet例如:telnet -e ^X host port

-E   滤除脱离字符。

-f   此参数的效果和指定”-F”参数相同。

-F   使用Kerberos V5认证时,加上此参数可把本地主机的认证数据上传到远端主机。

-k<域名>   使用Kerberos认证时,加上此参数让远端主机采用指定的领域名,而非该主机的域名。

-K   不自动登入远端主机。

-l<用户名称>   指定要登入远端主机的用户名称(主要用于传统 telnet server)。例如:telnet -l root 192.168.1.10

-L   允许输出8位字符资料。

-n<记录文件>   指定文件记录通信数据(调试用)。用法:telnet -n telnet.log host port

-r   使用类似rlogin指令的用户界面。

-S<服务类型>   设置telnet连线所需的IP TOS信息。

-x   假设主机有支持数据加密的功能,就使用它。

-X<认证形态>   关闭指定的认证形态。

telnet交互模式下的常用命令:

连接到远程服务后,按:

Ctrl + ]

进入 telnet 命令模式。常用命令有:

quit        退出 telnet

close      关闭当前连接

status     查看连接状态

open host port     打开新连接

set localecho        本地回显

toggle crlf           切换 CRLF

    例:

1 连接到远程主机的telnet服务

telnet 192.168.120.206

如果连接失败,排查步骤如下:

  • 确认ip地址是否正确?
  • 确认ip地址对应的主机是否已经开机?
  • 如果主机已经启动,确认路由设置是否设置正确?(使用route命令查看)

如果主机已经启动,确认主机上是否开启了telnet服务?(使用netstat命令查看,TCP的23端口是否有LISTEN状态的行),可以使用以下命令启动telnet服务service xinetd restart

  • 如果主机已经启动telnet服务,确认防火墙是否放开了23端口的访问?(使用iptables-save查看)

主机名可以换成域名,例如:

telnet www.baidu.com

2 测试 TCP 连接是否可达

telnet 127.0.0.1 6379

可能出现以下结果:

  • 连接成功,意味着6379端口开放 + TCP 通
  • Connection refused,意味着端口未监听
  • Connection timed out,意味着网络 / 防火墙问题

这是 telnet 最常见用途(80% 场景)。

3 作为“通用 TCP 客户端”

telnet 不关心上层协议,只管:把你输入的字符,通过 TCP 发给对方。所以你可以用它来测试:HTTP、SMTP、Redis(文本命令)或自定义 TCP 文本协议。

示例:测试 HTTP

telnet example.com 80

然后输入:

GET / HTTP/1.1
Host: example.com

示例:测试 Redis

telnet 127.0.0.1 6379

输入:

PING

返回:

+PONG

telnet服务常用配置:

service telnet
{
    disable = no #启用
    flags = REUSE #socket可重用
    socket_type = stream #连接方式为TCP
    wait = no #为每个请求启动一个进程
    user = root #启动服务的用户为root
    server = /usr/sbin/in.telnetd #要激活的进程
    log_on_failure += USERID #登录失败时记录登录用户名
}

#配置允许登录的客户端列表
only_from = 10.0.0.2 #只允许10.0.0.2登录

#配置禁止登录的客户端列表
no_access = 10.0.0.{2,3,4}  #禁止10.08.0.2、10.0.0.3、10.0.0.4登录

#设置开放时段
access_times = 9:00-12:00 13:00-17:00 # 每天只有这两个时段开放服务

#配置用户只从某个地址登录telnet服务
bind = 10.0.0.2

telnet的局限性:

  • 明文传输用户名、密码等敏感数据(非常不安全),不适合生产环境登录。生产环境登录应该使用ssh。
  • 不能测试 UDP。
  • 不适合二进制协议,因为会乱码,只适合文本。

现代环境中 telnet 的“正确定位”是TCP 端口 / 文本协议的调试工具,而不是登录工具。

其他相关的网络工具:

  • nc (netcat):TCP / UDP 万能工具
  • curl:测试HTTP / HTTPS
  • ssh:用于安全登录
  • nmap:用于端口扫描,也能测 UDP

Telnet Man Page Lists “The source code is not comprehensible” as a BUG

Here’s the man page for the telnet command in an old Ubuntu release:

http://manpages.ubuntu.com/manpages/karmic/man1/telnet-ssl.1.html

Scroll all the way to the bottom and you’ll find this under BUGS:

The source code is not comprehensible.

The source package is here: http://packages.ubuntu.com/source/dapper/netkit-telnet

Download it and take a look — it’s genuinely hard to read. A quick scan reveals at least these issues:

  1. Indentation mixes spaces and tabs, so large parts of the code appear completely unindented.
  2. Heavy use of #if/#else and a ton of preprocessor macros, including some odd ones like:
#ifndef B19200
#define B19200 B9600
#endif
#ifndef B38400
#define B38400 B19200
#endif
  1. What looks like C++ written in C — there are actual class declarations in terminal.cc.
  2. Variable names are cryptic (lots of old, tmp, c1, c2, s1, s2, s3), function naming is inconsistent, and there’s basically no coding style guide.

It’s legitimately tough to follow.

Still, huge respect to whoever decided to call out the source code’s readability as an official BUG in the man page.

(via coolshell.cn)

A Quick Way to Test Laravel Database Connections

You can use Tinker to verify if your database connection is working:

php artisan tinker

Then inside Tinker, run:

DB::connection()->getPdo();

If the connection succeeds, you’ll get back PDO instance details. If it fails, you’ll see the actual error message (usually something helpful like credentials issues or host unreachable).

一图看懂OAuth 2.0协议

授权码授权模式和隐式授权模式的区别:

  • 授权码授权模式,把access token存储在服务器端(session或redis里)
  • 隐式授权模式,把access token直接返回给客户端并存储,无需交换授权码。此授权模式最常用于无法安全存储客户端凭据的JavaScript或移动应用程序

laravel-phone包实现电话号码验证、格式转换等功能

相信你的系统中也一定会有手机注册以及发送短信验证码的功能。那么验证用户填写的手机号是否规范合法就是我们完成后续功能的第一步。propaganistas/laravel-phone包为我们提供了非常强大且可靠的电话验证功能,并且适用于全球所有国家的号码验证。

安装

composer require propaganistas/laravel-phone

配置

服务提供者会被 Laravel 自动发现。在语言目录lang中,为每个 validation.php 语言文件添加一条额外的翻译:

'phone' => 'The :attribute field must be a valid number.',

在线工具网站

https://laravel-phone.herokuapp.com用于测试Laravel-Phone包中的电话号码验证组件。

验证请求字段

你可以在验证规则数组中使用phone关键字,或者使用 Propaganistas\LaravelPhone\Rules\Phone规则类来以更具表现力的方式定义规则。 要限制国家/地区,你可以明确指定允许的国家/地区的代码:

'my_input'       => 'phone:US,BE',
// 'my_input'    => (new Phone)->country(['US', 'BE'])

或者为了使功能更加灵活,还可以与另一个包含国家/地区代码的数据字段进行匹配。例如,要求用户的电话号码与用户提供的居住国家/地区匹配。请确保国家/地区字段的名称与电话号码字段的名称相同,但附加”_country”后缀以便laravel-phone包自动识别:

'my_input'            => 'phone',
// 'my_input'         => (new Phone)
'my_input_country'    => 'required_with:my_input',

或者将自定义的国家/地区字段名称作为参数传递给验证器:

'my_input'            => 'phone:custom_country_field',
// 'my_input'         => (new Phone)->countryField('custom_country_field')
'custom_country_field'  => 'required_with:my_input',

注意:国家代码应符合ISO 3166-1 alpha-2标准。

为了支持除白名单国家/地区之外的任何有效国际格式的电话号码,请使用INTERNATIONAL参数。当你预期接收来自特定国家/地区的本地格式号码,但同时也希望接受任何其他正确输入的国外号码时,此功能会非常有用:

'my_input'            => 'phone:INTERNATIONAL,BE',
// 'my_input'         => (new Phone)->international()->country('BE')

要指定电话号码类型的约束,请将允许的类型附加到参数后面,例如:

'my_input'       => 'phone:mobile',
// 'my_input'    => (new Phone)->type('mobile')
// 'my_input'    => (new Phone)->type(libphonenumber\PhoneNumberType::MOBILE)

最常见的类型是移动电话mobile和固定电话fixed_line,但你可以随意使用此处定义的任何电话号码类型。

在电话号码类型名称前加上感叹号即可将其列入黑名单。请注意,你不能同时使用白名单和黑名单:

'my_input'       => 'phone:!mobile',
// 'my_input'    => (new Phone)->notType('mobile')
// 'my_input'    => (new Phone)->notType(libphonenumber\PhoneNumberType::MOBILE)

你还可以使用LENIENT参数启用宽松验证。启用宽松验证后,系统只会检查数字的长度,而不会检查实际的运营商模式:

'my_input'       => 'phone:LENIENT',
// 'my_input'    => (new Phone)->lenient()

模型属性转换(cast)

为了方便对Eloquent模型属性进行自动类型转换,我们提供了两个转换类:

use Illuminate\Database\Eloquent\Model;
use Propaganistas\LaravelPhone\Casts\RawPhoneNumberCast;
use Propaganistas\LaravelPhone\Casts\E164PhoneNumberCast;

class User extends Model
{
    public $casts = [
        'phone_1' => RawPhoneNumberCast::class.':BE',
        'phone_2' => E164PhoneNumberCast::class.':BE',
    ];
}

这两个类都会自动将数据库中的值转换为PhoneNumber对象,以便在你的应用程序中进一步使用:

$user->phone // PhoneNumber object or null

在设置值时,它们都接受字符串值或PhoneNumber对象。RawPhoneNumberCast会将数据库值更改为原始输入号码,而E164PhoneNumberCast会将格式化的E.164电话号码写入数据库。

对于RawPhoneNumberCast类,需要指定电话号码所属国家/地区,才能正确地将原始号码解析为PhoneNumber对象。对于E164PhoneNumberCast类,如果待设置的值并非已采用某种国际格式,则也需要指定电话号码所属国家/地区,才能正确地转换该值。

这两个类以相同方式接受类型转换参数:

  • 如果存在名称相似但后缀为”_country”的属性(例如phone_country),则类型转换器会自动检测并使用该属性
  • 提供另一个属性的名称作为类型转换参数
  • 提供一个或多个国家/地区代码作为类型转换参数
public $casts = [
    'phone_1' => RawPhoneNumberCast::class.':country_field',
    'phone_2' => E164PhoneNumberCast::class.':BE',
];

重要提示:这两种类型转换都需要有效的电话号码才能顺利地进行PhoneNumber对象的转换。请在将电话号码设置到模型之前进行验证。有关如何验证电话号码,请参阅上节“验证请求字段”。

⚠️ 属性赋值和E164PhoneNumberCast

由于E164PhoneNumberCast的特性,如果电话号码不是国际格式,则需要提供有效的国家/地区代码。由于Laravel在设置属性时会立即执行类型转换,因此请务必在设置电话号码属性之前设置国家/地区代码属性。否则,E164PhoneNumberCast将遇到空的国家/地区代码值并抛出意外异常。

// 错误
$model->fill([
    'phone' => '012 34 56 78',
    'phone_country' => 'BE',
]);

// 正确
$model->fill([
    'phone_country' => 'BE',
    'phone' => '012 34 56 78',
]);

// 错误
$model->phone = '012 34 56 78';
$model->phone_country = 'BE';

// 正确
$model->phone_country = 'BE';
$model->phone = '012 34 56 78';

实用电话号码类PhoneNumber

电话号码可以封装在Propaganistas\LaravelPhone\PhoneNumber类中,从而为其添加实用的方法。在视图中或保存到数据库时,可以直接引用这些对象,它们会优雅地降级为E.164格式。

use Propaganistas\LaravelPhone\PhoneNumber;

(string) new PhoneNumber('+3212/34.56.78');                // +3212345678
(string) new PhoneNumber('012 34 56 78', 'BE');            // +3212345678

或者,你可以使用phone()辅助函数。它会返回一个Propaganistas\LaravelPhone\PhoneNumber实例,如果提供了$format参数,则返回格式化后的字符串:

phone('+3212/34.56.78');                // PhoneNumber instance
phone('012 34 56 78', 'BE');            // PhoneNumber instance
phone('012 34 56 78', 'BE', $format);   // string

格式化号码

可以多种方式格式化PhoneNumber实例:

$phone = new PhoneNumber('012/34.56.78', 'BE');

$phone->format($format);       // 见libphonenumber\PhoneNumberFormat
$phone->formatE164();          // +3212345678
$phone->formatInternational(); // +32 12 34 56 78
$phone->formatRFC3966();       // tel:+32-12-34-56-78
$phone->formatNational();      // 012 34 56 78

// 格式化后,即可直接从提供的国家/地区拨打该号码
$phone->formatForCountry('BE'); // 012 34 56 78
$phone->formatForCountry('NL'); // 00 32 12 34 56 78
$phone->formatForCountry('US'); // 011 32 12 34 56 78

// 格式化后的号码在手机上可以直接点击,然后可以用手机直接从指定的国家/地区拨打该号码
$phone->formatForMobileDialingInCountry('BE'); // 012345678
$phone->formatForMobileDialingInCountry('NL'); // +3212345678
$phone->formatForMobileDialingInCountry('US'); // +3212345678

号码信息

获取一些关于该号码的信息:

$phone = new PhoneNumber('012 34 56 78', 'BE');

$phone->getType();              // libphonenumber\PhoneNumberType::FIXED_LINE
$phone->isOfType('fixed_line'); // true    (or use $phone->isOfType(libphonenumber\PhoneNumberType::FIXED_LINE) )
$phone->getCountry();           // 'BE'
$phone->isOfCountry('BE');      // true

等值比较

比较两个号码相同还是不同:

$phone = new PhoneNumber('012 34 56 78', 'BE');

$phone->equals('012/34.56.76', 'BE')       // true
$phone->equals('+32 12 34 56 78')          // true
$phone->equals( $anotherPhoneObject )      // true/false

$phone->notEquals('045 67 89 10', 'BE')    // true
$phone->notEquals('+32 45 67 89 10')       // true
$phone->notEquals( $anotherPhoneObject )   // true/false

数据库注意事项

免责声明:不同应用程序处理电话号码的方式各不相同。因此,以下内容仅供参考,旨在启发思考;我们不提供相关技术支持。

将电话号码存储在数据库中一直是一个值得探讨的问题,而且并没有一劳永逸的解决方案(没有银弹)。一切都取决于你的应用程序需求。以下是一些需要考虑的因素,以及一个实现建议。你理想的数据库设置可能需要结合以下列出的一些要点。

中国国内注册TikTok显示“网络不稳定”的解决方法

在中国国内想要成功注册TikTok,需要满足以下前提条件:

1 移除SIM卡。只要TikTok检测到你的手机里有中国SIM卡,它就不让使用!

2 卸载字节跳动公司的所有国内App,例如抖音、今日头条等。以防止被TikTok识别为国内环境。

3 更改手机的系统语言和时区为米国。

4 开启VPN全局代理,代理IP设置为米国的IP。

5 使用米国的手机号码,例如Google Voice,进行注册TikTok。

以上以米国的工具为例,你使用其他不是中国的国家的工具也行。

通过127.0.0.1可以正常访问到虚拟机中的网站,但通过hosts文件中配置的域名访问就报503错误,原因是被v2rayN干扰

我使用virtualbox,主机是Windows 11,虚拟机是Ubuntu 24,配置了端口映射8086到8086。

网站在Ubuntu 24虚拟机里可以通过test.com:8086正常访问到,也可以通过127.0.0.1:8086正常访问到,这说明我的Nginx配置没有问题。我在Windows 11的C:\Windows\System32\drivers\etc\hosts里面配置了:
127.0.0.1 test.com
我在Windows 11里使用127.0.0.1:8086可以正常访问到Ubuntu 24虚拟机中的这个网站,但是使用test.com:8086访问不到,报503错误。

原因是被v2rayN干扰,清除系统代理后,使用test.com:8086就能正常访问虚拟机中的这个网站。更好解决方法是,打开v2rayN的设置->参数设置->系统代理设置窗口,填入要被v2rayN忽略的网站地址。这样这些网站就不会被v2rayN干扰了,同时我们也能在Windows里能正常使用v2rayN。