Add support for tracking more SFTP specific events

This commit is contained in:
DaneEveritt 2022-07-09 19:30:38 -04:00
parent 2e01891074
commit 33ab762f5a
No known key found for this signature in database
GPG key ID: EEA66103B3D71F53
5 changed files with 38 additions and 11 deletions

View file

@ -6,6 +6,7 @@ use Illuminate\Http\Request;
use Pterodactyl\Models\User;
use Pterodactyl\Models\Server;
use Illuminate\Http\JsonResponse;
use Pterodactyl\Facades\Activity;
use Pterodactyl\Models\Permission;
use phpseclib3\Crypt\PublicKeyLoader;
use Pterodactyl\Http\Controllers\Controller;
@ -51,6 +52,8 @@ class SftpAuthenticationController extends Controller
if ($request->input('type') !== 'public_key') {
if (!password_verify($request->input('password'), $user->password)) {
Activity::event('auth:sftp.fail')->property('method', 'password')->subject($user)->log();
$this->reject($request);
}
} else {
@ -62,13 +65,29 @@ class SftpAuthenticationController extends Controller
}
if (!$key || !$user->sshKeys()->where('fingerprint', $key->getFingerprint('sha256'))->exists()) {
// We don't log here because of the way the SFTP system works. This endpoint
// will get hit for every key the user provides, which could be 4 or 5. That is
// a lot of unnecessary log noise.
//
// For now, we'll only log failures due to a bad password as those are not likely
// to occur more than once in a session for the user, and are more likely to be of
// value to the end user.
$this->reject($request, is_null($key));
}
}
$this->validateSftpAccess($user, $server);
Activity::event('auth:sftp.success')->actor($user)
->subject($user)
->property(array_filter([
'method' => isset($key) ? 'ssh_key' : 'password',
'fingerprint' => isset($key) ? 'SHA256:' . $key->getFingerprint('sha256') : null,
]))
->log();
return new JsonResponse([
'user' => $user->uuid,
'server' => $server->uuid,
'permissions' => $this->permissions->handle($server, $user),
]);
@ -136,6 +155,8 @@ class SftpAuthenticationController extends Controller
$permissions = $this->permissions->handle($server, $user);
if (!in_array(Permission::ACTION_FILE_SFTP, $permissions)) {
Activity::event('server:sftp.denied')->actor($user)->subject($server)->log();
throw new HttpForbiddenException('You do not have permission to access SFTP for this server.');
}
}

View file

@ -92,7 +92,7 @@ class ActivityLogTransformer extends BaseClientTransformer
$str = trans('activity.' . str_replace(':', '.', $model->event));
preg_match_all('/:(?<key>[\w.-]+\w)(?:[^\w:]?|$)/', $str, $matches);
$exclude = array_merge($matches['key'], ['ip', 'useragent']);
$exclude = array_merge($matches['key'], ['ip', 'useragent', 'using_sftp']);
foreach ($model->properties->keys() as $key) {
if (!in_array($key, $exclude, true)) {
return true;

View file

@ -16,6 +16,10 @@ return [
'recovery-token' => 'Used two-factor recovery token',
'token' => 'Solved two-factor challenge',
'ip-blocked' => 'Blocked request from unlisted IP address for :identifier',
'sftp' => [
'success' => 'Logged in using SFTP',
'fail' => 'Failed SFTP log in',
],
],
'user' => [
'account' => [
@ -96,6 +100,9 @@ return [
'update' => 'Updated the ":action" task for the :name schedule',
'delete' => 'Deleted a task for the :name schedule',
],
'sftp' => [
'denied' => 'Blocked SFTP access due to permissions',
],
'settings' => [
'rename' => 'Renamed the server from :old to :new',
],

View file

@ -5,7 +5,7 @@ import Translate from '@/components/elements/Translate';
import { format, formatDistanceToNowStrict } from 'date-fns';
import { ActivityLog } from '@definitions/user';
import ActivityLogMetaButton from '@/components/elements/activity/ActivityLogMetaButton';
import { TerminalIcon } from '@heroicons/react/solid';
import { FolderOpenIcon, TerminalIcon } from '@heroicons/react/solid';
import classNames from 'classnames';
import style from './style.module.css';
import Avatar from '@/components/Avatar';
@ -65,10 +65,13 @@ export default ({ activity, children }: Props) => {
</Link>
<div className={classNames(style.icons, 'group-hover:text-gray-300')}>
{activity.isApi && (
<Tooltip placement={'top'} content={'Performed using API Key'}>
<span>
<TerminalIcon />
</span>
<Tooltip placement={'top'} content={'Using API Key'}>
<TerminalIcon />
</Tooltip>
)}
{activity.properties.using_sftp && (
<Tooltip placement={'top'} content={'Using SFTP'}>
<FolderOpenIcon />
</Tooltip>
)}
{children}

View file

@ -1,12 +1,8 @@
.icons {
@apply flex space-x-1 mx-2 transition-colors duration-100 text-gray-400;
& > span {
@apply px-1 py-px cursor-pointer hover:text-gray-50;
}
& svg {
@apply w-4 h-4;
@apply px-1 py-px cursor-pointer hover:text-gray-50 h-5 w-auto;
}
}