Add support for tracking more SFTP specific events
This commit is contained in:
parent
2e01891074
commit
33ab762f5a
5 changed files with 38 additions and 11 deletions
|
@ -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.');
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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',
|
||||
],
|
||||
|
|
|
@ -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>
|
||||
<Tooltip placement={'top'} content={'Using API Key'}>
|
||||
<TerminalIcon />
|
||||
</span>
|
||||
</Tooltip>
|
||||
)}
|
||||
{activity.properties.using_sftp && (
|
||||
<Tooltip placement={'top'} content={'Using SFTP'}>
|
||||
<FolderOpenIcon />
|
||||
</Tooltip>
|
||||
)}
|
||||
{children}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue